1. 程式人生 > >[codevs1099]字串變換 雙向BFS

[codevs1099]字串變換 雙向BFS

題目←

qbxt裡雙向BFS的例題……
網上好多題解用的是STL黑科技?

抱著練碼力的心態手寫了佇列+find+replace;
順便map大法好啊

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<map>
using namespace std;
const int MAXN = 20000 + 60;
struct zt
{
    string a,b;
}ch[MAXN];
string
a,b,s,t; int cnt; string q1[MAXN],q2[MAXN]; int head1,head2,tail1,tail2; bool same(string x,string y) { if(x.length() != y.length())return false; int len = x.length(); for(int i = 0;i < len;i ++) { if(x[i] != y[i])return false; } return true; } int check(string a,string
b,int st) { if(b.length() > a.length())return -1; int len1 = a.length(),len2 = b.length(); for(int i = st;i < len1;i ++) { if(a[i] == b[0]) { bool flag = true; for(int j = 0;j < len2;j ++) { if(a[i + j] != b[j]) { flag = false
; break; } } if(flag)return i; } } return -1; } map <string,bool> used1,used2; map <string,int> step1,step2; string re(string a,string b,string c,int pos) { string ans; ans = ""; int pos2 = pos + b.length(); int loc = 0; while(loc < pos) { ans += a[loc]; loc ++; } int len = c.length(); for(int i = 0;i < len;i ++) { ans += c[i]; loc ++; } len = a.length(); for(int i = pos2;i < len;i ++) { ans += a[i]; loc ++; } return ans; } int T,flag; bool F; int main() { //cin >> T; cin >> s >> t; while(cin >> a >> b) { ch[++ cnt].a = a; ch[cnt].b = b; } q1[tail1 ++] = s;q2[tail2 ++] = t; used1[s] = true; used2[t] = true; while(!same(q1[tail1 - 1],q2[tail2 - 1])) { F = 0; for(int i = 1;i <= cnt;i ++) { for(int j = 0;j < q1[head1].length();j ++) { int loc = check(q1[head1],ch[i].a,j); if(loc != -1) { j = loc + 1; string tmp = re(q1[head1],ch[i].a,ch[i].b,loc); if(used1[tmp])continue; F = 1; used1[tmp] = true; step1[tmp] = step1[q1[head1]] + 1; q1[tail1 ++] = tmp; if(used2[tmp]) { printf("%d",step1[tmp] + step2[tmp]); return 0; } //cout << flag << tmp << '\n'; } } } flag ^= 1; for(int i = 1;i <= cnt;i ++) { for(int j = 0;j < q2[head2].length();j ++) { int loc = check(q2[head2],ch[i].b,j); if(loc != -1) { j = loc + 1; string tmp = re(q2[head2],ch[i].b,ch[i].a,loc); if(used2[tmp])continue; F = 1; used2[tmp] = true; step2[tmp] = step2[q2[head2]] + 1; q2[tail2 ++] = tmp; if(used1[tmp]) { printf("%d",step1[tmp] + step2[tmp]); return 0; } //cout << flag << tmp << '\n'; } } } flag ^= 1; head1 ++; head2 ++; if(head1 == tail1 || head2 == tail2) { printf("NO ANSWER!\n"); return 0; } } return 0; }

其實……這是假的雙向BFS
感謝wwq大佬指出的bug
這裡寫圖片描述
按程式碼的搜尋順序,先擴充套件點2;再擴充套件點1
此時搜到相同解,路徑長度為4
事實上點1的兄弟節點還可能擴展出其它更優解,如圖
這裡寫圖片描述
路徑長度為3
綜上,正確寫法為先將某佇列中同一深度的點擴充套件完,再擴充套件另一佇列,保證深度嚴格遞增。