2352 - 字串变换

已知有两个字串A,B及一组字串变换的规则(至多6个规则):

<span style="line-height:1.5;">A1 -> B1</span> 

<span style="line-height:1.5;">A2 -> B2</span> 

规则的含义为:在 A中的子串A1可以变换为B1、A2可以变换为B2$...

<br />

例如:A='abcd' B='xyz'

&nbsp; 变换规则为:

&nbsp; 'abc'-&gt;'xu' 'ud'-&gt;'y' 'y'-&gt;'yz'

&nbsp; 则此时,A可以经过一系列的变换变为B,其变换的过程为:

     'abcd'->'xud'->'xy'->'xyz'

&nbsp; 共进行了三次变换,使得A变换为B

<br />

题目输入

每个测试文件只包含一组测试数据,每组输入的第一行输入两个字符串A和B

接下来若干行输入变换规则:

A B

A1 B1
... ...      /

所有字符串长度的上限为 20。

<br />

题目输出

对于每组输入数据,若在10步(包含10步)以内能将A变换为B,则输出最少的变换步数,否则输出"NO ANSWER!"。


输入/输出样例

题目输入

abcd wyz
abc xu
ud y
y yz

题目输出

3

C++解答

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

struct node
{
    char s[30];
    int dep;
} list1[5010],list2[5010];

char a[7][30],b[7][30];
int n;
bool check(char *s1,char *s2)
{
    if (strlen(s1)!=strlen(s2)) return false;
    for (int i=0;i<strlen(s1);i++)
        if (s1[i]!=s2[i]) return false;
    return true;
}
bool pan1(char *s,int i,int x)
{
    for (int j=i;j<i+strlen(a[x]);j++)
        if (s[j]!=a[x][j-i]) return false;
    return true;
}
bool pan2(char *s,int i,int x)
{
    for (int j=i;j<i+strlen(b[x]);j++)
        if (s[j]!=b[x][j-i]) return false;
    return true;
}
void bfs()
{
    int head1,tail1,head2,tail2,i,j,k,l;
    head1=tail1=head2=tail2=1;

    while (head1<=tail1 && head2<=tail2)
    {
        if (list1[head1].dep+list2[head2].dep>10)
        {
            printf("NO ANSWER!\n");
            return ;
        }
        for ( i=0;i<strlen(list1[head1].s);i++)
            for ( j=1;j<=n;j++)
                if (pan1(list1[head1].s,i,j))
                {
                  tail1++;
                  for (k=0;k<i;k++) list1[tail1].s[k]=list1[head1].s[k];

                  for (l=0;l<strlen(b[j]);l++,k++) list1[tail1].s[k]=b[j][l];

                  for (l=i+strlen(a[j]);l<=strlen(list1[head1].s);l++,k++)
                     list1[tail1].s[k]=list1[head1].s[l];

                  list1[tail1].s[k]='\0';
                  list1[tail1].dep=list1[head1].dep+1;

                  for (k=1;k<=tail2;k++)
                    if (check(list1[tail1].s,list2[k].s))
                    {
                       printf("%d\n",list1[tail1].dep+list2[k].dep);
                       return ;
                     }
                }

        for ( i=0;i<strlen(list2[head2].s);i++)
            for ( j=1;j<=n;j++)
                if (pan2(list2[head2].s,i,j))
                {
                  tail2++;
                  for (k=0;k<i;k++) list2[tail2].s[k]=list2[head2].s[k];
                  for ( l=0;l<strlen(a[j]);l++,k++) list2[tail2].s[k]=a[j][l];
                  for (l=i+strlen(b[j]);l<=strlen(list2[head2].s);l++,k++)
                    list2[tail2].s[k]=list2[head2].s[l];
                  list2[tail2].s[k]='\0';
                  list2[tail2].dep=list2[head2].dep+1;
                  for (k=1;k<=tail1;k++)
                    if (check(list1[k].s,list2[tail2].s))
                    {
                       printf("%d\n",list1[k].dep+list2[tail2].dep);
                       return ;
                    }
                }
        head1++; head2++;
    }
    printf("NO ANSWER!\n");
}

int main()
{

    scanf("%s%s",list1[1].s,list2[1].s);
    n=1;
    while (scanf("%s%s",a[n],b[n])!=EOF) n++;
    n--;
    list1[1].dep=list2[1].dep=0;
    bfs();
    return 0;
}
时间限制 1 秒
内存限制 125 MB
讨论 统计
上一题 下一题