URAL 1654 Cipher Message 解题报告

题目链接: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 }
原文地址:https://www.cnblogs.com/windysai/p/3246115.html