• [Luogu1032] 字串变换


    Description

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

    $ A_1 -> B_1 $

    $ A_2 -> B_2 $

    规则的含义为:在(A)中的子串(A_1)可以变换为(B_1)(A_2)可以变换为(B_2)…。

    例如:A=abcd,B=xyz

    变换规则为:

    abcxuudyyyz

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

    abcdxudxyxyz

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

    Input

    输入格式如下:

    (A) (B)

    (A_1)(B_1)

    (A_2)(B_2)​ //变换规则

    ... ...

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

    Output

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

    Sample Input

    abcd xyz
    abc xu
    ud y
    y yz
    

    Sample Output

    3
    

    题解

    由于这题求最小步数,所以我们可以用(BFS),用(Hash)压缩状态,再就纯考验代码能力了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    const int maxm=400010,N=231;
    char s1[N],s2[N],mp[10][3][N],Q[maxm][N];
    int l,r,nmp,Ans[maxm],Hash[maxm];
    
    void Read()
    {
    	scanf("%s %s",s1,s2);
    	nmp=1;
    	while(~scanf("%s %s",mp[nmp][1],mp[nmp][2]))
    		++nmp;
    	--nmp;
    }
    
    void Delete(char s[],int st,int len)//删除mp[][1]
    {
    	int ls=strlen(s)-len;
    	for(int i=st;i<ls;++i) s[i]=s[i+len];
    	s[ls]='';
    }
    
    void Insert(char s[],int st,char mpi[])//插入mp[][2]
    {
    	char tmp1[maxm],tmp2[maxm];
    	for(int i=0;i<st;++i) tmp1[i]=s[i];
    	tmp1[st]='';
    	int len=strlen(s);
    	for(int i=st;i<=len;++i) tmp2[i-st]=s[i];
    	strcpy(s,tmp1),strcat(s,mpi),strcat(s,tmp2);
    }
    
    int Calc(char s[])
    {
    	int Res=0,len=strlen(s);
    	for(int i=0;i<len;++i)
    	{
    		Res=Res*131+s[i],
    		Res&=0x07FFFFFF;
    	}
    	return Res%maxm;
    }
    
    void Bfs()
    {
    	l=r=1;
    	strcpy(Q[1],s1);
    	Ans[1]=0;
    	int p,QAQ; char ss[N],s[N];
    	while(l<=r&&Ans[l]<=10)
    	{
    		if(!strcmp(Q[l],s2))
    		{
    			printf("%d
    ",Ans[l]); return;
    		}
    		for(int i=1;i<=nmp;++i)
    		{
    			strcpy(ss,Q[l]);
    			p=strstr(ss,mp[i][1])-ss;
    			while(strstr(ss,mp[i][1])!=NULL)
    			{
    				strcpy(s,Q[l]),
    				Delete(s,p,strlen(mp[i][1])),
    				Insert(s,p,mp[i][2]);
    				QAQ=Calc(s);
    				if(Hash[QAQ])
    				{
    					ss[p]=' ',
    					p=strstr(ss,mp[i][1])-ss;
    					continue;
    				}
    				Hash[QAQ]=1;
    				strcpy(Q[++r],s); Ans[r]=Ans[l]+1;
    				ss[p]=' ',
    				p=strstr(ss,mp[i][1])-ss;
    			}
    		}
    		++l;
    	}
    	puts("NO ANSWER!");
    }
    
    int main()
    {
    	Read(),Bfs();
    	return 0;
    }
    

    本文作者:OItby @ https://www.cnblogs.com/hihocoder/

    未经允许,请勿转载。

  • 相关阅读:
    .NET2.0基础类库中的范型——FunctionalProgramming
    原则
    080711 30℃
    关于mcp
    080714 33℃
    080715 31℃
    080716 30℃
    11号
    iOS-调用系统的短信和发送邮件功能,实现短信分享邮件分享
    UIView总结
  • 原文地址:https://www.cnblogs.com/hihocoder/p/11408193.html
Copyright © 2020-2023  润新知