题意:
实力转载
题目大意:
已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s1,最顶的c块牌归为s2,依此循环下去。
现在输入s1和s2的初始状态 以及 预想的最终状态s12
问s1 s2经过多少次洗牌之后,最终能达到状态s12,若永远不可能相同,则输出"-1"。
解题思路:
很浅白的模拟题= = 不懂为什么别人要把它归类到广搜。。。所以我又重新分类了。。。
直接模拟就可以了,关键在于状态记录,然后判重
若s1和s2在洗牌后的状态,是前面洗牌时已经出现过的一个状态,且这个状态不是预想的状态S12,就说明无论怎样再洗牌都不可能达到S12了,因为这个洗牌操作已经陷入了一个“环”
如果状态没有重复过,则一直模拟洗牌,直至s12出现
记录状态可以用map<string,bool>vist
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
int main()
{
int t;
int io=0;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int step = 0;
char s1[220],s2[220],sz[220],sn[440];
scanf("%s%s%s",s1,s2,sz);
map<string,int> vis;
printf("%d ",++io);
while(1)
{
int i,tp=0;
for(i = 0; i <n; i++)
{
sn[tp++] = s2[i];
sn[tp++] = s1[i];
}
step++;
sn[tp]='\0';
if(strcmp(sn,sz)==0)
{
printf("%d\n",step);
break;
}
if(vis[sn])
{
printf("-1\n");
break;
}
vis[sn]=1;
tp = 0;
for(i = 0; i < n; i++)
s1[i] = sn[i];
s1[n] = '\0';
for(i = n; i < 2*n; i++)
s2[tp++] = sn[i];
s2[n] = '\0';
}
}
return 0;
}