想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:
有两堆牌,S1与S2,现在取上c张牌为S2,下c张牌为S1,洗牌的时候,S1的第一张牌放在最上面,然后交叉合并两堆牌,接着再洗,再合并。
问输入S1与S2,经过多少次洗牌后能够到达目的的洗牌的顺序。若不能输出-1
解题思路:
这是一个模拟题目,唯一让人思考的地方是怎么判断不能到达那个顺序,解决这个问题的方法是,记录每次洗牌的顺序,如果洗牌的时候到达以前出现过的顺序,并且还没有到达目的顺序,那么肯定的,是不能到达目的顺序
代码:
#include <iostream>
using namespace std;
struct Node{
char s[210];
struct Node * next;
}*head,*p,*q,*last;
int main(){
char s1[210],s2[210],skey[210],stemp[210];
int n,c,key,i,k;
scanf("%d",&n);
for(k=1;k<=n;k++){
scanf("%d%s%s%s",&c,s2,s1,skey);
head=(Node *)malloc(sizeof(Node));
head->next=NULL;
last=head;
key=0;
while(1){
for(i=0;i<c;i++){ //洗牌
stemp[2*i]=s1[i];
stemp[2*i+1]=s2[i];
}
stemp[2*i]='\0';
key++;
if(!strcmp(stemp,skey)){ //与目的牌的顺序比较
printf("%d %d\n",k,key);
break;
}
bool flag=false; //判断是否出现过
q=head;
while(q->next!=NULL){
if(!strcmp(q->s,stemp)){
flag=true;
break;
}
q=q->next;
}
if(flag) {
printf("%d -1\n",k);
break;
}
q=(Node *)malloc(sizeof(Node)); //合并两堆牌
strcpy(q->s,stemp);
last->next=q;
last=q;
q->next=NULL;
for(i=0;i<c;i++){
s2[i]=stemp[i];
s1[i]=stemp[i+c];
}
}
}
return 0;
}