例题6-4 破损的键盘 UVa11988

来源:互联网 发布:node.js 手机 编辑:程序博客网 时间:2024/05/17 05:09

1.题目描述:点击打开链接

2.解题思路:本题利用链表解决。每输入一个字符,就把它存起来,设输入字符串是s[1...n],则可以用Next[i]表示在当前显示屏中s[i]右边的字符编号。为了便于后续处理,假设s的最前面还有一个虚拟的s[0](这是链表的常用处理方式,请务必牢记),那么Next[0]就表示显示屏中最左边的字符,再用一个变量cur表示光标位置:即当前光标位于s[cur]的右边(即我们的DOS窗口中经常出现的下一个待输入的位置)。cur=0说明光标位于s[0]的右边,即显示屏的最左边。为了移动光标,还需要一个变量last表示显示屏的最后一个字符是s[last]。

接下来考虑如何用链表来实现本题。最初我们需要一个头结点,不妨将它设为0,即Next[0]=0。头结点只是起到一个标记的作用,不表示真实的位置。链表中的头结点总是指向链表的第一个元素。然后开始插入元素。链表中插入元素就两句代码:Next[i]=head;head=i。第一句表示新元素i的下一个元素指向当前head指向的元素,第二句话是更新head的指向,指向新的第一个元素i。当所有元素插入完毕后,只需要从头结点开始,顺着Next数组即可按顺序输出整个链表。注意,这样的插入实际上是在尾部插入,链表的尾部在不断地变长。这道题中用cur来当做头结点,通过移动头结点的位置即可实现在链表的不同位置插入新元素。根据题意,当遇到‘['时,头结点变为0,遇到‘]'时,头结点变为last即可。详细过程见代码注释。

3.代码:

#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define N 100000+5int last, cur, Next[N];char s[N];int main(){//freopen("t.txt", "r", stdin);while (~scanf("%s", s + 1)){int n = strlen(s + 1);last = cur = 0;Next[0] = 0;for (int i = 1; i <= n; i++){char ch = s[i];if (ch == '[')cur = 0;//头结点移到位置0else if (ch == ']')cur = last;//头结点移到位置lastelse//进行插入操作{Next[i] = Next[cur];Next[cur] = i;if (cur == last)last = i;cur = i;}}for (int i = Next[0]; i != 0; i = Next[i])//按顺序输出链表printf("%c", s[i]);cout << endl;}return 0;}

0 0