祖玛消消消(恶心)

【问题描述】


祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干
个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到
轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立
即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。
开发商最近准备为玩家写一个游戏过程的回放工具。 他们已经在游戏内完成
了过程记录的功能,而回放功能的实现则委托你来完成。
游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做
的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。


【输入格式】


第一行是一个由大写字母'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;
}

 

posted @ 2016-11-06 15:21  IIIIIIIIIU  阅读(645)  评论(0编辑  收藏  举报