[codevs1099]字串變換 雙向BFS
阿新 • • 發佈:2019-01-24
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
綜上,正確寫法為先將某佇列中同一深度的點擴充套件完,再擴充套件另一佇列,保證深度嚴格遞增。