题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1654
题意:简单的理解就是,把一个序列中相邻的且是偶数个相同的字符删除,奇数个的话就只保留一个。但是要注意,删除的过程中,可能会导致本来不相邻的相同字符变得相邻了,这时候也要删除。如果直接暴力:每次查看串中是否有相同的相邻字母,如果有就删去,然后继续从前向后查找,这样肯定会超时(O(N^2))。
优化的方法,利用栈的特殊结构O(N),从左向右扫描,判断当前的字符和栈顶元素是否相同,如果相同栈顶元素出栈,否则的话将这一位的元素入栈,这样线性地扫描一遍后,栈中的元素就是剩下的串。要注意输出时候不能直接从top开始,而是要逆序输出。
1 #include <iostream> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 using namespace std; 6 7 const int MAXN = 200000 + 10; 8 char ch[MAXN], s[MAXN]; 9 10 int main() 11 { 12 int i, top, len; 13 while (gets(ch)) 14 { 15 top = 0; 16 len = strlen(ch); 17 memset(s, 0, sizeof(s)); 18 for (i = 0; i < len; i++) 19 { 20 if (s[top] != ch[i]) // 注意,初始化的s[top=0] = 0,所以第一个元素ch[0]肯定是进栈的,从s[top=1]开始保存 21 { 22 s[++top] = ch[i]; // 注意,++top不能写成top++,否则下一轮的判断指示不了栈顶元素,而是指示了栈顶元素的再上一个位置,导致判断失效
23 } 24 else 25 { 26 top--; 27 } 28 } 29 for (i = 1; i <= top; i++) 30 { 31 cout << s[i]; 32 } 33 cout << endl; 34 } 35 return 0; 36 }