[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]='\0';
}

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]='\0';
	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\n",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;
}
posted @ 2019-08-25 16:00  OItby  阅读(162)  评论(0编辑  收藏  举报