题目描述
已知有两个字串 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!"
输入输出样例
输入样例#1:
abcd xyz
abc xu
ud y
y yz
输出样例#1:
3
出这道题的人真的是丧心病狂,这题没什么思维难度,但是很考代码能力。
我看到有人stl一下就过了,但是我做的可能比较麻烦,广搜加字符串hash。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
y=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*y;
}
int len1,len2;
int now=1;
char begin[45],aim[45];
char chan[45][2][45];
int lon[45][2];
char t[100045][45];
char tmp[45];
char ne[45];
int lenth;
int len[100045];
int bu[100045];
int head,tail=1;
bool vis[100000045];
int P=31,T=100000007;
bool flag=0;
il void bfs()
{
for(int i=0;i<len1;i++)
t[0][i]=begin[i];
ll l=0;
for(int i=0;i<len1;i++)
l=(l*P+begin[i]+T)%T;
vis[l]=1;
len[0]=len1;//³õʼÈë¶Ó
while(head!=tail)
{
if(len[head]==len2)
{
int p=0;
for(int i=0;i<len2;i++)
if(t[head][i]==aim[i])
p++;
else
break;
if(p==len2)
{
flag=1;
printf("%d\n",bu[head]);
return;
}
}
if(bu[head]==10)
{
flag=1;
printf("NO ANSWER!\n");
return;
}
for(int i=0;i<len[head];i++)
tmp[i]=t[head][i];
lenth=len[head];
head++;//tmp±£´æ¶ÓÊ×
for(int i=0;i<lenth;i++)//Ñ»·Ã¿¸ö×Ö·û¿ªÊ¼
{
for(int j=1;j<=now;j++)//ÿ¸ö¿ÉÒÔת»»µÄ¹æÔò
{
if(i+lon[j][0]>lenth)//cannt change
continue;
int p=0;
for(int k=0;k<lon[j][0];k++)//¿´¿´¿É²»¿ÉÒÔת»»
{
if(tmp[i+k]==chan[j][0][k])
p++;
else
break;
}
if(p==lon[j][0])//be able to change,enter the queue
{
for(int k=0;k<i;k++)
ne[k]=tmp[k];
for(int k=0;k<lon[j][1];k++)
ne[i+k]=chan[j][1][k];
for(int k=i+lon[j][0];k<lenth;k++)
ne[k-lon[j][0]+lon[j][1]]=tmp[k];
len[tail]=lenth-lon[j][0]+lon[j][1];
if(len[tail]>20)
continue;
ll l=0;
for(int k=0;k<len[tail];k++)
l=(l*P+ne[k]+T)%T;
if(vis[l])
continue;
vis[l]=1;
for(int k=0;k<len[tail];k++)
t[tail][k]=ne[k];
bu[tail]=bu[head-1]+1;
tail++;
}
}
}
}
}
int main()
{
scanf("%s%s",begin,aim);// ¿ªÊ¼µÄ×Ö·û´®ºÍÄ¿±ê
len1=strlen(begin);
len2=strlen(aim);
while(scanf("%s%s",chan[now][0],chan[now][1])!=EOF)//ÊäÈë¿Éת»»µÄ×Ö·û´®
{
lon[now][0]=strlen(chan[now][0]);
lon[now][1]=strlen(chan[now][1]);
now++;
}
bfs();
if(flag==0)
printf("NO ANSWER!\n");
return 0;
}