POJ 3087 Shuffle'm Up模拟

点击打开链接

题目大意:


已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,
再将s12的最底下的c块牌归为s1,最顶的c块牌归为s2,依此循环下去。

现在输入s1和s2的初始状态 以及 预想的最终状态s12

问s1 s2经过多少次洗牌之后,最终能达到状态s12,若永远不可能相同,则输出"-1"。

注意
给两堆牌S1和S2(ABC和BCA),注意给的每一堆牌的顺序是从下到上,先拿S2这一堆的最底下的那张牌即B,
再拿S1的最底下A,以此类推,得到S12(BACBAC),

这个S12的顺序也是从下到上的顺序,然后最底下C张变成原来的S1,最顶上C张变成S2,
重复操作,判断到某一个S12 状态需要操作的次数。

而且放牌也是有顺序的 即 最上面一定放s1[n-1];  即 s[2*n-1]=s1[n-1];

最下面一定放s2[0];s[0]=s2[0];

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define PI acos(-1)
#define eps 0.00000001
#define LL long long
using namespace std;
char s1[1000],s2[1000],s3[1000];
string s;
int main()
{
    int T,n;
    scanf("%d",&T);
    map<string,int>Q;
    for(int Cas=1; Cas<=T; Cas++)
    {
        scanf("%d%s%s%s",&n,s1,s2,s3);
        s=s3;
        printf("%d ",Cas);
        int num=0;
        while(1)
        {
          int   index = 0;
            for (int j = 0; j < n; ++j)
            {
                s[index++] = s2[j];    ///此牌的序列是倒着的 ,即前面的号是最下面的    s[0]为最下面的
                s[index++] = s1[j];     ///此牌的序列是倒着的 ,即前面的号是最下面的
            }
            num++;
            if(s==s3)
            {
                printf("%d\n",num);
                break;
            }
            if(Q[s])
            {
                printf("-1\n");
                break;
            }
            else
            {
                for(int i=0; i<n; i++)
                {
                    s1[i]=s[i];                ///牌的最后n个数是 对应着 s的前n 个数
                    s2[i]=s[i+n];
                }
                for (int j = 0; j < n; ++j)
                {
                    s[index++] = s2[j];      ///始终保持 s2[0]放到最下面
                    s[index++] = s1[j];        /// s1[n-1]放在最上面
                }
                Q[s]=1;
            }
        }
    }
    return 0;
}


你可能感兴趣的:(POJ 3087 Shuffle'm Up模拟)