1. 程式人生 > >牛客練習賽31: D. 神器大師泰茲瑞與威穆(連結串列)

牛客練習賽31: D. 神器大師泰茲瑞與威穆(連結串列)

連結:https://ac.nowcoder.com/acm/contest/218/D
來源:牛客網
 

題目描述

「只要我拉動繩線,你就得隨之起舞。」          ——泰茲瑞

 

       泰茲瑞來到卡拉德許之後,由於他精湛的神器製造技術,可謂是過的如魚得水。這次,他為自己打造了一個編輯器,稱為威穆(Veim)。操作威穆時,有兩種模式,具體操作如下。

Normal Mode

- 按下 i :進入 Insert Mode
- 按下 f

:緊接著一個小寫字母 char,若當前游標後(右)方有至少一個 char ,將游標移動到其所在位置,否則不移動。
- 按下 x :刪除當前游標所在位的字元,後面的字元均會前移一格。
- 按下 h :將游標向左(前)移動一格,若無法移動就不移動。
- 按下 l :將游標向右(後)移動一格,若無法移動就不移動。
- 若按下了其他字元:無任何效果。

Insert Mode

- 按下非 e 小寫字母 char :在游標當前位置前插入這個字母 char。
- 按下 e :退出 Insert Mode(進入 Normal Mode)。 

       (具體請見樣例)

       現在泰茲瑞的威穆中已經寫入了一個字串 s 。接下去泰茲瑞進行了一波操作(按下了若干按鍵),他的按鍵序列為 t 。現給出 s 和 t ,求這波操作之後威穆內留下的字串。

輸入描述:

兩行,第一行字串 s ,第二行字串 t 。

輸出描述:

一行,威穆裡最後留下的字串。

輸入

applese
xfllhlia

輸出

pplaese

 

手寫個連結串列按題意模擬就好了

每個節點存有當前字元ch,以及R[]表示所有字元下一個出現的位置節點,如果沒有就指向尾巴

其中R[]可以像線段樹那樣懶惰更新

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<list>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
typedef struct Node
{
	char ch;
	Node *next, *last, *R[30];
}Node;
Node *head, *tail, *now;
char s1[100005], s2[100005];
void Insert(Node *p, char ch)
{
	int i;
	Node *temp;
	temp = new Node;
	temp->ch = ch;
	temp->next = p;
	temp->last = p->last;
	for(i=0;i<=26;i++)
	{
		temp->R[i] = (p->last)->R[i];
		if(ch-'a'==i)
			(p->last)->R[i] = temp;
	}
	(p->last)->next = temp;
	p->last = temp;
}
void Erase(Node *p)
{
	int ch;
	ch = p->ch-'a';
	(p->last)->R[ch] = p->R[ch];
	(p->last)->next = p->next;
	(p->next)->last = p->last;
	delete(p);
}
Node* ToRight(Node *p, char ch)
{
	if(p->R[ch-'a']!=tail)
		return p->R[ch-'a'];
	else
		return p;
}
void Print(Node *p)
{
	while(p!=tail)
	{
		p = p->next;
		printf("%c", p->ch);
	}
	printf("\n");
}
int main(void)
{
	char ch;
	int n, m, i, j, op;
	scanf("%s%s", s1+1, s2+1);
	n = strlen(s1+1);
	m = strlen(s2+1);
	tail = new Node, head = new Node;
	head->next = tail, tail->last = head;
	for(i=0;i<=26;i++)
		head->R[i] = tail;
	now = tail;
	for(i=1;i<=n;i++)
		Insert(now, s1[i]);
	while(now->last!=head)
	{
		if(now!=tail)
		{
			for(j=0;j<=26;j++)
			{
				(now->last)->R[j] = now->R[j];
				if(now->ch-'a'==j)
					(now->last)->R[j] = now;
			}
		}
		now = now->last;
	}
	op = 1;
	for(i=1;i<=m;i++)
	{
		//Print(head);
		ch = s2[i];
		if(op==1)
		{
			if(ch=='i')
				op = 2;
			else if(ch=='f')
			{
				ch = s2[++i];
				now = ToRight(now, ch);
			}
			else if(ch=='x')
			{
				now = now->next;
				Erase(now->last);
			}
			else if(ch=='h')
			{
				if(now!=tail)
				{
					for(j=0;j<=26;j++)
					{
						(now->last)->R[j] = now->R[j];
						if(now->ch-'a'==j)
							(now->last)->R[j] = now;
					}
				}
				if(now->last!=head)
					now = now->last;
			}
			else if(ch=='l')
			{
				if(now->next!=tail)
					now = now->next;
			}
		}
		else
		{
			if(ch=='e')
				op = 1;
			else
				Insert(now, ch);
		}
	}
	Print(head);
	return 0;
}
/*
aaaabaaaab
fbhhhhfbxhhhhfbikehhhhhhhhhhhhhhbkx
*/