【NOIP2002】字串变换

一道难得的搜索好题,题目大意很简单,这里不再赘述,主要说一下思路

当然普通的bfs答案是正确的,但是在CH上评测会TLE一个点,所以我们采用效率更高的双向bfs

从初始状态和目标状态分别搜索,建立两个队列,分别扩展状态。如果一个队列扩展的状态已经被另一个队列搜索过了,那么便出现答案了。

另外,使用map可以对字符串进行标记,replace可以自动替换字符串,详见代码。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <map>
 6 #include <algorithm>
 7 #include <string>
 8 using namespace std;
 9 string a,b,aa[10],bb[10];
10 int n=1;
11 queue<string> q1;
12 queue<string> q2;
13 map<string,int> vis;
14 map<string,int> dis;
15 string now,noww,neww;
16 int main() {
17     cin>>a>>b;
18     while(cin>>aa[n]>>bb[n]) n++;
19     n--;
20     q1.push(a);
21     q2.push(b);
22     vis[a]=1;
23     vis[b]=2;
24     dis[a]=0; dis[b]=0;
25     if(a==b) {
26         puts("0");
27         return 0;
28     }
29     while((!q1.empty())&&(!q2.empty())) {
30         if(q1.size()<=q2.size()) {
31             now=q1.front();
32             q1.pop();
33             int d=dis[now];
34             for(int i=1;i<=n;i++) {
35                 noww=now;
36                 while(1) {
37                     int m=noww.find(aa[i]);
38                     if(m==-1) break ;
39                     neww=now;
40                     neww.replace(m,aa[i].size(),bb[i]);
41                     if(vis[neww]!=1) {
42                         if(vis[neww]==2) {
43                             if(dis[neww]+d+1<=10) printf("%d
",dis[neww]+d+1);
44                             else puts("NO ANSWER!"); 
45                             return 0;
46                         }
47                         vis[neww]=1;
48                         dis[neww]=d+1;
49                         q1.push(neww);
50                     }
51                     noww[m]='!';
52                 }
53             }
54         }
55         else {
56             now=q2.front();
57             q2.pop();
58             int d=dis[now];
59             for(int i=1;i<=n;i++) {
60                 noww=now;
61                 while(1) {
62                     int m=noww.find(bb[i]);
63                     if(m==-1) break ;
64                     neww=now;
65                     neww.replace(m,bb[i].size(),aa[i]);
66                     if(vis[neww]!=2) {
67                         if(vis[neww]==1) {
68                             if(dis[neww]+d+1<=10) printf("%d
",dis[neww]+d+1);
69                             else puts("NO ANSWER!");
70                             return 0;
71                         }
72                         vis[neww]=2;
73                         dis[neww]=d+1;
74                         q2.push(neww);
75                     }
76                     noww[m]='!';
77                 }
78             }
79         }
80     }
81     puts("NO ANSWER!");
82     return 0;
83 }
AC Code
原文地址:https://www.cnblogs.com/shl-blog/p/10587042.html