https://cn.vjudge.net/problem/UVA-11988#author=pangda
题意:
同学的键盘出现了奇妙的故障,所有键都会正常的工作,但是键盘上的Home以及End键有时候会莫名其妙的自己按下。但是盲打很熟练的他一般习惯关闭显示器打字,因为这样很酷。
现在他正在打一段文本,假设你已经知道这段文本以及Home和End键会什么时候出现故障自行按下。请你编写一个程序,求出他最后打出的文本。
分析:如果使用vector插入删除,会超时因为数组元素的移动很耗时间,所有选择链表list,直接模拟即可。
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("i.txt","r",stdin);
string str;
while(getline(cin, str)) {
list<char> list1;
auto it=list1.begin();
for(int i = 0; i < str.length(); i++) {
if(str[i]=='[') it=list1.begin();
else if(str[i]==']') it=list1.end();
else list1.insert(it,str[i]);
}
for(auto itt=list1.begin(); itt!=list1.end(); itt++)
cout << *itt;
cout << endl;
}
}
紫书写法:
#include<bits/stdc++.h>
using namespace std;
char s[101000];
int Next[101000];
//这里用一个Next数组模拟指向,Next[i]表示当前显示屏中s[i]右边的字符下标。
//再用一个cur表示当前光标的位置,last表示最后一个字符的记录位置,
//这样遇到End键,就能直接找到光标下一 个指向的字符位置了。
int main() {
freopen("i.txt","r",stdin);
int cur,last;//cur为光标位置,last为显示屏最后一个字符
while(~scanf("%s",s+1)) {
memset(Next,0,sizeof(Next));
int len = strlen(s+1);
Next[0] = 0;
cur = last = 0;
for(int i = 1; i <= len; i++) {
if(s[i] == '[') cur = 0;
else if(s[i] == ']') cur = last;
else {
//模拟插入链表过程
Next[i] = Next[cur];//第i个字符指向光标位置
Next[cur] = i;//光标指向下一个字符
if(cur == last)//只有光标在当前最后一个字符位置或是遇到]后才执行
last = i;
cur = i;//移动光标
}
}
for(int i = Next[0]; i != 0; i = Next[i])
printf("%c",s[i]);
printf("\n");
memset(s,0,sizeof(s));
}
return 0;
}