P1124字串变换
描述
已知有两个字串 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!"
限制
每个测试点1s
来源
noip2002提高组第二题
解析:设从正向开始扩展的状态储存在q数组,[l1,l2]为当前正向扩展出的状态,p数组以及l2,r2的定义类似。
正向每扩展出一个状态,就在[l2,r2]中暴力查找是否存在相同的状态,若有,则得到答案。
逆向扩展与正向扩展类似。
我这里采用的是交替扩展,即正向扩展一次,然后逆向扩展一次。当然,也可以每次选择状态数更少的那个进行扩展,实际上这种方法更好。
代码:
#include<cstdio>
#include<cstring>
#define maxn 100000
#define max_len 50
using namespace std;
char q[maxn+10][max_len+10];
char p[maxn+10][max_len+10];
char x[10][max_len],y[10][max_len];
int n=0,add[10],xl[10],yl[10];
int main()
{
int i,j,k,xx,step,len;
char jiewei;
scanf("%s%s",q[0],p[0]);
jiewei=p[0][strlen(p[0])];
while(scanf("%s%s",x[n],y[n])==2)
{
xl[n]=strlen(x[n]),yl[n]=strlen(y[n]);
add[n]=yl[n]-xl[n];
n++;
}
if(n==0)
{
if(strcmp(q[0],p[0])==0)printf("0\n");
else printf("NO ANSWER!\n");
return 0;
}
int l1=0,r1=0,s1=0;
int l2=0,r2=0,s2=0;
for(step=1;step<=5;step++)
{
for(i=0;i<n;i++)
for(j=l1;j<=r1;j++)
for(len=strlen(q[j]),k=0;k<len && len+add[i]<max_len;k++)
if(strncmp(x[i],q[j]+k,xl[i])==0)
{
s1++;
strncpy(q[s1],q[j],k);
strncpy(q[s1]+k,y[i],yl[i]);
strncpy(q[s1]+k+yl[i],q[j]+k+xl[i],len-k-xl[i]);
q[s1][len+add[i]]=jiewei;
for(xx=l2;xx<=r2;xx++)
if(strcmp(p[xx],q[s1])==0)
{
printf("%d\n",step+step-1);
return 0;
}
}
if(s1!=r1)l1=r1+1,r1=s1;
for(i=0;i<n;i++)
for(j=l2;j<=r2;j++)
for(len=strlen(p[j]),k=0;k<len && len-add[i]<max_len;k++)
if(strncmp(y[i],p[j]+k,yl[i])==0)
{
s2++;
strncpy(p[s2],p[j],k);
strncpy(p[s2]+k,x[i],xl[i]);
strncpy(p[s2]+k+xl[i],p[j]+k+yl[i],len-k-yl[i]);
p[s2][len-add[i]]=jiewei;
for(xx=l1;xx<=r1;xx++)
if(strcmp(q[xx],p[s2])==0)
{
printf("%d\n",step+step);
return 0;
}
}
if(s2!=r2)l2=r2+1,r2=s2;
}
printf("NO ANSWER!\n");
return 0;
}
题目讨论
08-23 | 这个题目比较屌…… |
05-11 | 样例输出什么情况 |
03-24 | C++的在Linux不能过? |
10-31 | P1124疑难 |
10-12 | 诡异的编译失败…请大牛帮忙 |
10-12 | 一个题目理解方面的问题 |
07-21 | 215 |
03-19 | 使用C语言,此题能AC吗? |
02-07 | 大牛来一下 |