字串变换

Posted lyxzhz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字串变换相关的知识,希望对你有一定的参考价值。

题目描述

已知有两个字串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。

共进行了3次变换,使得A变换为B。

输入格式

输入格式如下:

A B
A1 B1
A2 B2 |-> 变换规则

... ... /

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

输出格式

输出至屏幕。格式如下:

若在10步(包含10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"


思路:BFS

输入时用f数组记录变换规则,并记录种数。枚举每一种变换规则,因为在同一字符串A中可能有很多重复的A1所处的位置不同,所以要用while,同时将处理过的位置打标记。使用hash判重。本题容易想到BFS但对于字符串的处理是难点,所以专门用了两个函数处理变换过程。

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=231,M=400009;
char a[N],b[N],s1[N],s2[N],f[10][3][N],q[M][N];
int tot,ans[M],Hash[M];

 void init()

    scanf("%s %s",a,b);
    while (scanf("%s %s",s1,s2)!=EOF)
    
        strcpy(f[++tot][1],s1);
        strcpy(f[tot][2],s2);
    

 void delete1(char s[],int sum,int len)

    int j=sum;
    for (int i=sum+len; i<strlen(s); i++)
    
        s[j]=s[i]; j++;
    
    s[j]='\0';

 void join(char s[],char st[],int sum)

    char a1[N],a2[N],j=0;
    for (int i=0; i<sum; i++)  a1[i]=s[i]; 
    a1[sum]='\0';
    for (int i=sum; i<strlen(s); i++)
    
        a2[j]=s[i]; j++;
    
    a2[j]='\0';
    strcpy(s,a1); strcat(s,st); strcat(s,a2); 

 int Hashh(char s[])

    long long res=0;
    int i=0; 
    while (i<strlen(s))
    
        res+=res*131+s[i];
        res=(res&0x07FFFFFF);
        i++;
    
    return res%M;

 void bfs()

    int l=0,r=1,sum;
    strcpy(q[1],a); ans[1]=0;
    while (l<r&&ans[l+1]<=10)
    
        l++;
        for (int i=1; i<=tot; i++)
        
            strcpy(s1,q[l]);
            sum=strstr(s1,f[i][1])-s1;
            while (strstr(s1,f[i][1])!=NULL)
            
                strcpy(s2,q[l]);
                delete1(s2,sum,strlen(f[i][1]));
                join(s2,f[i][2],sum);
                int k=Hashh(s2);
                if (Hash[k]!=0)
                
                    s1[sum]=' ';
                    sum=strstr(s1,f[i][1])-s1;
                    continue;
                
                Hash[k]=1;
                r++; strcpy(q[r],s2); ans[r]=ans[l]+1;
                if (strcmp(s2,b)==0)
                
                    printf("%d\n",ans[r]);
                    return;
                
                s1[sum]=' ';
                sum=strstr(s1,f[i][1])-s1;
            
        
    
    printf("No Solution!\n");


 int main()

    init();
    bfs();
    return 0;

以上是关于字串变换的主要内容,如果未能解决你的问题,请参考以下文章

NOIP2002 字串变换题解(双向搜索)

codevs1099 字串变换

P1032 字串变换

1099 字串变换

[NOIP2002]字串变换 T2 双向BFS

luogu P1032 字串变换