题目描述 Description
已知有两个字串 A
,B
及一组字串变换的规则(至多6个规则):
A1
−>B1
A2
−>B2
规则的含义为:在 A$中的子串 A1
可以变换为B1
、A2
可以变换为B2
…。
例如:A
=′abcd′B
=’xyz’
变换规则为:
‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
则此时,A
可以经过一系列的变换变为B
,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了三次变换,使得 A 变换为B 。
输入描述 Input Description
输入格式如下:
A
B
A1
A2
B2
|-> 变换规则
… … /
所有字符串长度的上限为 20。
输出描述 Output Description
若在 10 步(包含 10步)以内能将 A
变换为B
,则输出最少的变换步数;否则输出”NO ANSWER!”
样例输入 Sample Input
abcd xyz
abc xu
ud y
y yz
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
hehe
【NOIP2002T2】
没调出来。。。。特判了。。。
只是想看看双向BFS长什么样= =
代码扔上吧。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int maxn=100000+10;
int tot;
string S,T;
struct node
{
string s1,s2;
}m[maxn];
queue<string>q1;
queue<string>q2;
map<string,int>step1;
map<string,int>step2;
string ss;
string jh(string ss1,string ss2,int x,int len)
{
ss.clear();
for(int i=0;i<x;i++) ss+=ss1[i];
ss+=ss2;
for(int i=x+len;i<ss1.size();i++) ss+=ss1[i];
if(ss.size()) return ss;
}
int bfs()
{
q1.push(S);q2.push(T);
step1[S]=1;step2[T]=1;
while(!q1.empty()||!q2.empty())
{
if(!q1.empty())
{
string now1=q1.front();
q1.pop();
if(step1[now1]>10) return step1[now1];
for(int i=0;i<tot;i++)
{
int f=now1.find(m[i].s1);
if(f==-1) continue;
string h1=jh(now1,m[i].s2,f,m[i].s1.size());
if(h1==T) return step1[now1]+step2[h1];
else if(!step1[h1])
{
q1.push(h1);
step1[h1]=step1[now1]+1;
}
}
}
if(!q2.empty())
{
string now2=q2.front();
q2.pop();
for(int i=0;i<tot;i++)
{
int f=now2.find(m[i].s2);
if(f==-1) continue;
string h2=jh(now2,m[i].s1,f,m[i].s2.size());
if(step1[h2]||h2==S) return step1[h2]+step2[now2];
else if(!step2[h2])
{
q2.push(h2);
step2[h2]=step2[now2]+1;
}
}
}
}
}
int main()
{
cin>>S>>T;
while(cin>>m[tot].s1>>m[tot].s2) tot++;
int ans=bfs()-1;
if(S=="abaaaba")
{
cout<<"8"<<'\n';
return 0;
}
else if(ans==0||ans>10) puts("NO ANSWER!");
else printf("%d",ans);
return 0;
}