首页 > 代码库 > poj 3087 Shuffle'm Up (模拟)

poj 3087 Shuffle'm Up (模拟)

链接:poj 3087

题意:有两堆牌s1,s2,牌数都为c,将s2,s1按给定规则相互交叉组成一堆牌s12,

再将s12最底下的c块给s1,最顶端的c块给s2,依此循环下去,

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

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

分析:直接简单模拟此规则就行,关键是如何判断是否永远不可能达到预想的s12,

若s1和s2在洗牌后的状态,是前面洗牌时已经出现过的一个状态,且这个状态不是预想的状态S12,

就说明无论怎样再洗牌都不可能达到S12了,因为这个洗牌操作已经陷入了一个“环”

如果状态没有重复过,则一直模拟洗牌,直至s12出现

#include<stdio.h>
#include<string.h>
int main()
{
    int n,m,i,j,k,sum,flag;
    char s1[105],s2[105],t[100][210],s[210];
    scanf("%d",&n);
    for(k=1;k<=n;k++){
        scanf("%d",&m);
        scanf("%s%s%s",s1,s2,s);
        j=0;
        flag=1;
        for(sum=1;;sum++){
            for(i=0;i<m;i++){      //将s2,s1合成s12
                t[j][i*2]=s2[i];  
                t[j][i*2+1]=s1[i];
            }
            t[j][m*2]=0;      //记得添加空字符
            if(strcmp(t[j],s)==0)          //判断是否与预想状态相同
                break;
            for(i=0;i<j;i++)     
                if(strcmp(t[i],t[j])==0){   //判重  
                    flag=0;
                    break;
                }
            if(!flag){
                sum=-1;
                break;
            }
            strncpy(s1,t[j],m);      //将s12分成s1,s2
            strncpy(s2,t[j]+m,m);
            j++;
        }
        printf("%d %d\n",k,sum);
    }
    return 0;
}