poj 3087 Shuffle'm Up(bfs)
题目:http://poj.org/problem?id=3087
题意:
给你两堆纸牌,让你通过数次洗牌动作使得洗牌之后的序列为给定序列。输出最小的洗牌次数。
洗牌方法:
把第二堆的第一张放在最下面,让后放第一堆最下面的那张,;轮流放。
洗完之后,把下面的n张作为第一堆,上面的n张作为第二堆。
做法:
模拟纸牌的放法,一步步的放,当序列符合的时候就终止放。
当纸牌的顺序和一开始的顺序相同的时候就输出-1。
注意:经过n次洗牌之后,一定会得到和最开始的序列相同的时候,此时就是循环结
代码:
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int num1[110],num2[110]; 6 int nums[210]; 7 int nume[210]; 8 int num[210]; 9 int flag; 10 int cmp(int a[],int b[],int n) 11 { 12 int i; 13 for(i=0;i<n;i++) 14 { 15 if(a[i]!=b[i]) 16 return 0; 17 } 18 return 1; 19 } 20 int main() 21 { 22 int t,n,k,i; 23 char c; 24 cin>>t; 25 k=0; 26 while(t--) 27 { 28 k++; 29 memset(num1,0,sizeof(num1)); 30 memset(num2,0,sizeof(num2)); 31 memset(nums,0,sizeof(nums)); 32 memset(nume,0,sizeof(nume)); 33 memset(num,0,sizeof(num)); 34 scanf("%d%*c",&n); 35 for(i=0;i<n;i++) 36 { 37 scanf("%c",&c); 38 nums[i]=c-'A'; 39 num1[i]=c-'A'; 40 } 41 getchar(); 42 for(i=0;i<n;i++) 43 { 44 scanf("%c",&c); 45 nums[i+n]=c-'A'; 46 num2[i]=c-'A'; 47 } 48 getchar(); 49 for(i=0;i<2*n;i++) 50 { 51 scanf("%c",&c); 52 nume[i]=c-'A'; 53 } 54 getchar(); 55 flag=0; 56 int sum=0; 57 for(i=0;i<n;i++) 58 { 59 num[2*i]=num2[i]; 60 num[2*i+1]=num1[i]; 61 } 62 printf("%d ",k); 63 /*for(i=0;i<n;i++) 64 { 65 cout<<num1[i]<<" "; 66 } 67 cout<<endl; 68 for(i=0;i<n;i++) 69 { 70 cout<<num2[i]<<" "; 71 } 72 cout<<endl; 73 for(i=0;i<2*n;i++) 74 { 75 cout<<nums[i]<<" "; 76 } 77 cout<<endl; 78 for(i=0;i<2*n;i++) 79 { 80 cout<<nume[i]<<" "; 81 } 82 cout<<endl; 83 for(i=0;i<2*n;i++) 84 { 85 cout<<num[i]<<" "; 86 } 87 cout<<endl;*/ 88 while(1) 89 { 90 if(cmp(nume,num,2*n)) 91 { 92 if(sum==0) 93 { 94 cout<<sum+1<<endl; 95 break; 96 } 97 cout<<sum<<endl; 98 break; 99 } 100 if(cmp(num,nums,2*n)) 101 { 102 cout<<"-1"<<endl; 103 break; 104 } 105 for(i=0;i<n;i++) 106 { 107 num[i*2]=num2[i]; 108 num[i*2+1]=num1[i]; 109 } 110 for(i=0;i<n;i++) 111 { 112 num2[i]=num[i+n]; 113 num1[i]=num[i]; 114 } 115 sum++; 116 } 117 } 118 return 0; 119 }