码迷,mamicode.com
首页 > 其他好文 > 详细

字串变换

时间:2019-08-25 16:01:41      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:math   ini   重复   %s   include   ret   res   sum   int   

题目描述

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

字串变换

标签:math   ini   重复   %s   include   ret   res   sum   int   

原文地址:https://www.cnblogs.com/lyxzhz/p/11408038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!