题意:将一个字符串从初始状态变换为目标状态,最多有6种变换规则,如果10步之内能完成,输出步数.
分析:又是一道有关字符串的搜索题,思路很简单,把初始状态放入队列里开始跑广搜,枚举所有变换规则,能变就变,变完就入队,队列为空和步数超过10都表示不能完成变换任务.稍微剪下枝就可以了.
int num=1;
string a,b,turna[7],turnb[7];
queue<string> Q;
queue<int> ans;
map<string,int> visit;
bool bfs(){
while(Q.size()&&Q.front()!=b&&ans.front()<=10){
//如果队列里还有元素,且还没达到目标状态,且步数小于10
if(visit[Q.front()]){
Q.pop();ans.pop();
continue;
}//剪枝:如果之前这个状态搜索过,就跳过
//枚举num中变换规则:
for(int i=1;i<=num;i++){
string s1=Q.front();
visit[s1]=1;
while(1){
int pos=s1.find(turna[i]);
//在要被变换的字符串s1中找是否有可以变换的子串
if(pos==-1)break;
//找不到就退出,找得到就对s2开始进行变换:
string s2=Q.front();
s2.replace(pos,turna[i].size(),turnb[i]);
//熟悉字符串replace的用法:
//从字符串s2的pos下标起,长度为turna[i].size()
//变换为turnb[i]
Q.push(s2);//变换后入队
ans.push(ans.front()+1);
s1[place]='|';
//将s1里子串turna[i]的这次出现位置随便换成另一种字符
//这样就可以查找到s1里子串turna[i]的下一个出现位置
}
}
Q.pop();ans.pop();
}
if(!Q.size()||ans.front()>10)return 0;
return 1;
}
int main(){
cin>>a>>b;
Q.push(a);//初始状态入队
ans.push(0);//初始状态步数为0
//Q队列和ans队列里面的元素一一对应.
while(cin>>turna[num]>>turnb[num])num++;
num--;
//读入num种变换规则
int pd=bfs();
if(!pd) puts("NO ANSWER!");
else printf("%d
",ans.front());
return 0;
}