本题用迭代优先搜索的方法实现了一次。但是的话,相比较而言,双向BFS的方法会更好一些,因为其自带层数,方便判断,向外延伸扩展时也可以用map判重。
这题读来是一道标准的双向BFS模板题,有初末状态,当两边搜索到相交的状态的时候,两者路径之和即为当前路径下的步数。
实现过程中的难点:
1.如何实现双向:弄两个队列,两个转换函数,分别对其进行转化,塞进队列中
#include<cstring>
#include<cstdio>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
struct pel{
string cur;
int step;
};
map<string,int>mark;
map<string,char> jud;
queue<pel> q1,q2;
string book1[7],book2[7];
string bgi,edi;
int best=1e6,top=0;
void bfs(){
pel now1,now2,temp;
int i,loc;
now1.cur=bgi,now1.step=0,now2.cur=edi,now2.step=0;
q1.push(now1),q2.push(now2);
string next1,next2,tem,tempo;
while(true){
if(q1.empty()||q2.empty())break;(有可能两边有剩余的,而部分接头的答案就藏在接头的部分里面)
now1.cur=q1.front().cur,now1.step=q1.front().step,q1.pop();
if(now1.step+1>10)continue;(大于10直接退出)
for(i=1;i<=top;i++){
tem=book1[i];
loc=now1.cur.find(tem,0);(确定位置在哪)
for(;loc!=-1;loc=now1.cur.find(tem,loc+1)){
tempo=now1.cur;(锁定字符串)
next1=tempo.replace(loc,tem.length(),book2[i]);
if(mark[next1]&&jud[next1]=='b')continue;(如果是自己一头的并且已经找过那么就不用往下搜了(之前的肯定更小))
if(mark[next1]+now1.step+1>10)continue;(如果目标大于10也中断)
if(jud[next1]=='e'){(如果接头了就比比大小,然后就不必找了)
best=min(best,mark[next1]+now1.step+1);
break;
}
if(mark[next1]==0)mark[next1]=1e6;(要是没走过给他个大的值方便下面运行)
if(mark[next1]>=now1.step+1){
temp.cur=next1;
jud[next1]='b';
temp.step=now1.step+1;
q1.push(temp);
mark[next1]=now1.step+1;
}
}
}
now2.cur=q2.front().cur,now2.step=q2.front().step,q2.pop();
if(now2.step+1>10)continue;(这部分和上面部分是一样的)
for(i=1;i<=top;i++){
tem=book2[i];
loc=now2.cur.find(tem,0);
for(;loc!=-1;loc=now2.cur.find(tem,loc+1)){
tempo=now2.cur;
next2=tempo.replace(loc,tem.length(),book1[i]);
if(mark[next2]&&jud[next2]=='e')continue;
if(mark[next2]+now2.step+1>10)continue;
if(jud[next2]=='b'){
best=min(best,mark[next2]+now2.step+1);
break;
}
if(mark[next2]==0)mark[next2]=1e6;
if(mark[next2]>=now2.step+1){
temp.cur=next2;
jud[next2]='e';
temp.step=now2.step+1;
q2.push(temp);
mark[next2]=now2.step+1;
}
}
}
}
}
int main(){
cin>>bgi>>edi;
jud[bgi]='b';
jud[edi]='e';
string a,b;
while(top<6&&cin>>a>>b){(读入)
top++;
book1[top]=a;
book2[top]=b;
}
bfs();
if(best==1e6)printf("NO ANSWER!");
else printf("%d",best);
}
总结:双向BFS模板题,然后的话复习了下字符串函数和结构体队列,加深了对于记忆化搜索的印象(菜菜瑟瑟发抖,写的代码有点臃肿QAQ)