题目链接:http://poj.org/problem?id=3087
题目大意:已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s1,最顶的c块牌归为s2,依此循环下去。
现在输入s1和s2的初始状态 以及 预想的最终状态s12。问s1 s2经过多少次洗牌之后,最终能达到状态s12,若永远不可能相同,则输出"-1"。
解题思路:照着模拟就好了,只是判断是否永远不能达到状态s12需要用map,定义map<string,int>mp,记录出现过的s1和s2合并产生的字符串,如果某一次s1、s2合并后产生的字符串曾经出现过,那说明会一直循环下去,也就无法到达状态s12了。
代码:
1 #include<cstdio> 2 #include<queue> 3 #include<map> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 8 9 int main(){ 10 int T; 11 scanf("%d",&T); 12 int cas=0; 13 while(T--){ 14 char s1[105],s2[105],s3[205],res[205]; 15 int len; 16 scanf("%d",&len); 17 scanf("%s%s%s",s1+1,s2+1,res+1); 18 map<string,int>mp; 19 int ans=0; 20 while(1){ 21 ans++; 22 for(int i=1;i<=2*len;i++){ 23 if(i%2) 24 s3[i]=s2[(i+1)/2]; 25 else 26 s3[i]=s1[i/2]; 27 } 28 s3[2*len+1]='\0'; 29 for(int i=1;i<=2*len;i++){ 30 if(i<=len) 31 s1[i]=s3[i]; 32 else 33 s2[i-len]=s3[i]; 34 } 35 if(strcmp(res+1,s3+1)==0) 36 break; 37 if(mp.find(s3)==mp.end()) 38 mp[s3]=1; 39 else{ 40 ans=-1; 41 break; 42 } 43 } 44 printf("%d %d\n",++cas,ans); 45 } 46 return 0; 47 }