zoukankan      html  css  js  c++  java
  • 字串变换

    题目描述

    已知有两个字串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;
    }
    
  • 相关阅读:
    四、Signalr手持令牌验证
    三、Signalr外部链接
    三、使用Fiddler劫持网络资源(手机端)
    一、数据库层搭建
    学会聊天
    weblogic实时监控开发
    jrockit静默安装笔记
    自动磁盘分区脚本
    WebsphereMQ搭建集群
    Websphere MQ Cluster
  • 原文地址:https://www.cnblogs.com/lyxzhz/p/11408038.html
Copyright © 2011-2022 走看看