【NOIP2002】字串變換
阿新 • • 發佈:2019-03-24
替換字符 分享 urn size click 但是 put emp div
一道難得的搜索好題,題目大意很簡單,這裏不再贅述,主要說一下思路
當然普通的bfs答案是正確的,但是在CH上評測會TLE一個點,所以我們采用效率更高的雙向bfs
從初始狀態和目標狀態分別搜索,建立兩個隊列,分別擴展狀態。如果一個隊列擴展的狀態已經被另一個隊列搜索過了,那麽便出現答案了。
另外,使用map可以對字符串進行標記,replace可以自動替換字符串,詳見代碼。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5AC Code#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\n",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\n",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 }
【NOIP2002】字串變換