字串变换

题目描述

已知有两个字串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;
}
posted @ 2019-08-25 15:24  Allen_Gun  阅读(284)  评论(0编辑  收藏  举报