题目链接:http://poj.org/problem?id=3087
题意:就是洗牌,有两副牌s1,s2。1,每次s2下面取一张,再从s1下面取一张,直到s1,s2取完形成一副新的牌s12
2,再把下面的一半牌分给s1,上面一半分给s2。再重复1。
问至少多少歩达到目标状态。
分析: 自己做的第一道有关字符串的搜索,感觉题量还是太小,当时没有想到如何剪枝,偷看了别人题解,oh,用map啊,那么问题就迎刃而解了。另外还有一些细节需要注意,例如输出的格式,不要太激动了,歩百里者半九十。一点点的粗心就是WA!
code:
#include<string>
#include<map>
#include<iostream>
#include<queue>
using namespace std;
struct node{int step;string ss;}s;
int k;//the count of cards;
string s1,s2,s12,target;
void divide(){
s1="",s2="";//先将s1,s2清空
for(int i=0;i<2*k;++i){
if(i<k)s1+=s12[i];
else s2+=s12[i];
}
}
void shuffle(){
s12="";//同理,将s12清空
for(int i=0;i<k;++i){
s12+=s2[i];
s12+=s1[i];
}
}
void bfs(){
map<string,int>m;//剪枝,判断当前状态是否出现过
queue<node>q;
while(!q.empty())q.pop();
shuffle();//unite the s1,s2;
s.step=1;s.ss=s12;
q.push(s);
while(!q.empty()){
node no=q.front();q.pop();
if(!m[no.ss]){
m[no.ss]=1;
// cout<<"s12="<<s12<<endl;
if(s12==target){cout<<no.step<<endl;return;}
divide();
shuffle();
no.step++;
no.ss=s12;
q.push(no);
}
}
cout<<"-1"<<endl;
}
int main(void){
int T;cin>>T;
int CASE=0;
while(T--){
cin>>k;
cin>>s1>>s2>>target;
cout<<++CASE<<" ";
bfs();
}
}