来看一下这道wzoi.cc中的题目:
题目描述:
已知有两个字串 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$。
输入格式:
A$ B$
A1$ B1$ \
A2$ B2$ | --> 若干变换规则
... ... /
所有字符串长度的上限为 20。
输出格式:
若在 10 步(包含 10步)以内能将 A$ 变换为 B$ ,则输出最少的变换步数;否则输出"NO ANSWER!"
样例输入:
abcd xyz abc xu ud y y yz
样例输出:
3
时间限制: 1000ms
空间限制: 128MB
代码:
用深搜会超时,这里用广搜,具体代码如下:
#include<bits/stdc++.h>
using namespace std;
int j;
string s1,s2,a[100],b[100],n,m;
map<string,int>h;
struct data{
string s;
int step;
};
void bfs()
{
queue<data>q;
q.push({s1,0});
h[s1]=1;
while(!q.empty())
{
string s=q.front().s;
int step=q.front().step;
if(step>10)
{
return;
}
if(s==s2)
{
printf("%d",step);
exit(0);
}
q.pop();
for(int i=1;i<=j;i++)
{
int t=0;
while(int(s.find(a[i],t))!=-1)
{
string ss=s;
int o=s.find(a[i],t);
s.replace(o,a[i].size(),b[i]);
if(h[s]==0)
{
q.push({s,step+1});
h[s]=1;
}
s=ss;
t=o+1;
}
}
}
}
int main()
{
cin>>s1>>s2;
while(cin>>n>>m)
{
a[++j]=n;
b[j]=m;
}
bfs();
printf("NO ANSWER!");
return 0;
}
今天就写到这,我是wzoissb下次见!