题目链接:
POJ-3087
题目大意:
两个长度相同的字符串表示两副扑克牌,按s2-s1-s2-s1…s2-s1的顺序一次叠加,称为一次洗牌操作,洗牌后上半部分为new s2 下半部分为new s1 ,现在要求洗牌多少次可以达到某个特定序列,如果不能输出-1
思路:
因为只有一条路可以走,勉强算是个搜索。
拿n=3实验一下可以发现,循环到原来的串了,因此只要map判断串是否出现过,即可判断是否可行,否则一直循环下去就行。
//证明上是显然的,因为面对下一次洗牌时,永远是未知的,不知道下一次是否会出现序列,是否会成功。
代码实现:
#include <iostream>
#include <cstring>
#include <queue>
#include <string>
#include <cstdio>
#include <map>
using namespace std;
#define mem(s,t) memset(s,t,sizeof s)
const int MAXN=110;
int n;
string s1,s2,s,ac;
map<string,int> m;
int solve(){
int cnt=1;
while(1){
s="";
for(int i=0;i<n;i++){
s=s+s2[i]+s1[i];
}
if(s==ac) return cnt;
if(m[s]){
return -1;
}
m[s]=1;
s1=s.substr(0,n);
s2=s.substr(n,n);
cnt++;
}
}
int main(){
int t,kase=0;
cin>>t;
while(t--){
cin>>n>>s1>>s2>>ac;
m.clear();
int ans=solve();
if(ans+1) cout<<++kase<<" "<<ans<<endl;
else cout<<++kase<<" "<<-1<<endl;
}
return 0;
}