P1032 字串变换 字符串

题目描述

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

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

输入输出格式

输入格式:

 

键盘输人文件名。文件格式如下:

A B A1 B1 \

   A2 B2 |-> 变换规则

... ... /

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

 

输出格式:

 

输出至屏幕。格式如下:

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

 

输入输出样例

输入样例#1:
abcd xyz
abc xu
ud y
y yz
输出样例#1:
3

出这道题的人真的是丧心病狂,这题没什么思维难度,但是很考代码能力。
我看到有人stl一下就过了,但是我做的可能比较麻烦,广搜加字符串hash。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define ll long long
#define il inline
#define db double

using namespace std;

il int gi()
{
	int x=0,y=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
		{
			if(ch=='-')
				y=-1;
			ch=getchar();
		}
	while(ch>='0'&&ch<='9')
		{
			x=x*10+ch-'0';
			ch=getchar();
		}
	return x*y;
}

int len1,len2;

int now=1;

char begin[45],aim[45];

char chan[45][2][45];

int lon[45][2];

char t[100045][45];

char tmp[45];

char ne[45];

int lenth;

int len[100045];

int bu[100045];

int head,tail=1;

bool vis[100000045];

int P=31,T=100000007;

bool flag=0;

il void bfs()
{
	for(int i=0;i<len1;i++)
		t[0][i]=begin[i];
	ll l=0;
	for(int i=0;i<len1;i++)
		l=(l*P+begin[i]+T)%T;
	vis[l]=1;
	len[0]=len1;//³õʼÈë¶Ó
	
	while(head!=tail)
		{
			if(len[head]==len2)
				{
					int p=0;
					for(int i=0;i<len2;i++)
						if(t[head][i]==aim[i])
							p++;
						else
							break;
					if(p==len2)
						{
							flag=1;
							printf("%d\n",bu[head]);
							return;
						}
				}
			
			if(bu[head]==10)
				{
					flag=1;
					printf("NO ANSWER!\n");
					return;
				}	
			
			for(int i=0;i<len[head];i++)
				tmp[i]=t[head][i];
				
			lenth=len[head];
			head++;//tmp±£´æ¶ÓÊ×
			
			for(int i=0;i<lenth;i++)//Ñ­»·Ã¿¸ö×Ö·û¿ªÊ¼
				{
					for(int j=1;j<=now;j++)//ÿ¸ö¿ÉÒÔת»»µÄ¹æÔò
						{
							if(i+lon[j][0]>lenth)//cannt change
								continue;
							int p=0;
							for(int k=0;k<lon[j][0];k++)//¿´¿´¿É²»¿ÉÒÔת»»
								{
									if(tmp[i+k]==chan[j][0][k])
										p++;
									else
										break;
								}
								
							if(p==lon[j][0])//be able to change,enter the queue
								{	
									for(int k=0;k<i;k++)
										ne[k]=tmp[k];
									for(int k=0;k<lon[j][1];k++)
										ne[i+k]=chan[j][1][k];
									for(int k=i+lon[j][0];k<lenth;k++)
										ne[k-lon[j][0]+lon[j][1]]=tmp[k];
									len[tail]=lenth-lon[j][0]+lon[j][1];
									if(len[tail]>20)
										continue;
									
									ll l=0;
									for(int k=0;k<len[tail];k++)
									l=(l*P+ne[k]+T)%T;
									if(vis[l])
										continue;
										
									vis[l]=1;
									for(int k=0;k<len[tail];k++)
										t[tail][k]=ne[k];
									bu[tail]=bu[head-1]+1;
									tail++;
								}
						}
				}
			
		}
}

int main()
{
	scanf("%s%s",begin,aim);// ¿ªÊ¼µÄ×Ö·û´®ºÍÄ¿±ê
	len1=strlen(begin);
	len2=strlen(aim);

	while(scanf("%s%s",chan[now][0],chan[now][1])!=EOF)//ÊäÈë¿Éת»»µÄ×Ö·û´®
		{
			lon[now][0]=strlen(chan[now][0]);
			lon[now][1]=strlen(chan[now][1]);
			now++;
		}
	
	bfs();
	
	if(flag==0)
		printf("NO ANSWER!\n");
	
	return 0;
}

  

posted @ 2017-10-15 14:49  GSHDYJZ  阅读(280)  评论(0编辑  收藏  举报