祖玛消消消(恶心)
【问题描述】
祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干
个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到
轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立
即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。
开发商最近准备为玩家写一个游戏过程的回放工具。 他们已经在游戏内完成
了过程记录的功能,而回放功能的实现则委托你来完成。
游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做
的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。
【输入格式】
第一行是一个由大写字母'A'~'Z'组成的字符串, 表示轨道上初始的珠子序列,
不同的字母表示不同的颜色。
第二行是一个数字?,表示整个回放过程共有?次操作。
接下来的?行依次对应于各次操作。每次操作由一个数字?和一个大写字母?
描述, 以空格分隔。 其中, ?为新珠子的颜色。 若插入前共有?颗珠子, 则? ∈ [0,?]
表示新珠子嵌入之后(尚未发生消除之前)在轨道上的位序。
【输出格式】
输出共?行,依次给出各次操作(及可能随即发生的消除现象)之后轨道上
的珠子序列。
如果轨道上已没有珠子,则以“-”表示。
【样例输入】
ACCBA
5
1 B
0 A
2 B
4 C
0 A
【样例输出】
ABCCBA
AABCCBA
AABBCCBA
-
A
【样例解释】
你以为山里又有座钟神的庙?
【数据规模与约定】
100%的数据满足1 ≤ ? ≤ 10 3 ,1 ≤ ? ≤ 2× 10 3 。
思路:
这题恶心的要死,神奇的大模拟,钟神说了,这个题要用链表写,但是
我是一枚渣渣的蒟蒻
只会用数组来模拟,所以写了一个特别特别直白的模拟
祖玛这个游戏没怎么玩过,所以,其中有几项消除的规则我是不知道的。。
代码写起来也非常吃力,但是我还是顽强的写了出来;
这个消除的情况有很多种,总结以下几种消除方法:
1.当插入一个元素,前后相同的元素加上插入的元素的个数大于2时会消除;
2.在1的情况下前后都有相同的元素,并且相同元素的个数大于2时会消除;
3.在1成立,但2不成立的情况下,已经消除的元素后面的相同的元素个数大于2会消除;
来,上代码;
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,cur; char str[6002],ch,vn; void change(int now) { if(str[now]==0) str[now]=str[now-1]; else { change(now+1); str[now]=str[now-1]; } } void qread(int &x) { x=0;vn=getchar(); while(vn<'0'||vn>'9') vn=getchar(); while(vn>='0'&&vn<='9'){x=x*10+(int)(vn-'0');vn=getchar();} } void check(int now,char ty) { int l=now-1,r=now,nl=0,nr=0,pd=0; while(1) { if(str[l]==ty) nl++,l--; if(str[r]==ty) nr++,r++; if(str[l]!=ty&&str[r]!=ty) break; } if(nl+nr+1>=3) { while(1) { nl=0,nr=0,ty=str[l]; int ll=l,rr=r; int kol; while(1) { kol=0; if(str[l]==ty) l--,nl++,kol++; if(str[r]==ty) r++,nr++,kol++; if(kol==0) break; } if(nl==0||nr==0||nl+nr<3) { l=ll,r=rr; break; } } while(1) { int rr=r,kol=0; nr=0; if(str[r]!=0) { char op=str[r]; while(1) { if(str[r]==op) { nr++; r++; } else break; } } if(nr<3) { r=rr; break; } } while(1)//因为在第3种情况消除完之后可能会出现第二种情况,所以在用一次处理第二种情况的方法; { nl=0,nr=0,ty=str[l]; int ll=l,rr=r; int kol; while(1) { kol=0; if(str[l]==ty) l--,nl++,kol++; if(str[r]==ty) r++,nr++,kol++; if(kol==0) break; } if(nl==0||nr==0||nl+nr<3) { l=ll,r=rr; break; } } int kol=r-l-1; for(int i=l+1;i<r;i++) str[i]=0; while(str[r]!=0) { str[r-kol]=str[r]; str[r]=0; r++; } } else { change(now+1); str[now]=ty; } } void print() { if(str[0]==0) { putchar('-'); putchar('\n'); return; } int kcc=0; while(str[kcc]!=0) { putchar(str[kcc]); kcc++; } putchar('\n'); } int main() { gets(str);//因为可能开始序列为空,二维空时cin和scanf都难读入,所以这里用gets if(str[0]=='\n') str[0]=0; qread(n); for(int i=1;i<=n;i++) { qread(cur); cin>>ch; check(cur,ch); print(); } return 0; }