• luogu 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

    bfs+hash,我比较蠢,不会STL
    #include<cstdio> 
    #include<cstring>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    #define LL long long
    const int maxn = 100007;
    int P=31;
    char s[51],t[51],len[51][2],tf[51][2][51];int cnt=1,len1,len2;
    int mod=100000007,que[maxn],can[maxn],step[maxn];char tmp[maxn][51],tt[maxn];
    bool vis[100000009];
    bool bfs() {
        for(int i=0;i<len1;++i) tmp[0][i]=s[i];
        LL h1=0;
        for(int i=1;i<len1;i++) h1=(h1*P+s[i]+mod)%mod;
        vis[h1]=1;
        que[0]=len1;
        int head=0,tail=1;
        while(head!=tail) {
            if(que[head]==len2) {
                int p=0;
                for(int i=0;i<len2;++i) 
                    if(tmp[head][i]==t[i])p++;
                    else break;
                if(p==len2) {
                    printf("%d
    ",step[head]);return 1;
                }
                if(step[head]==10) return 0;    
            }
            for(int i=0;i<que[head];++i) 
                tt[i]=tmp[head][i];
            int lenth=que[head];head++;
            //printf("%d
    ",lenth);
            for(int i=0;i<lenth;i++) {
                for(int j=1;j<=cnt;j++) {
                    if(i+len[j][0]>lenth)continue;
                    int p=0;
                    for(int k=0;k<len[j][0];k++) {
                        if(tt[i+k]==tf[j][0][k])p++;
                        else break;
                    }
                    //printf("%d
    ",p);
                    if(p==len[j][0]) {  //can transfrom
                        for(int k=0;k<i;k++) 
                            can[k]=tt[k];
                        for(int k=0;k<len[j][1];k++)can[i+k]=tf[j][1][k];
                        for(int k=i+len[j][0];k<lenth;k++)
                            can[k-len[j][0]+len[j][1]]=tt[k];
                        que[tail]=lenth-len[j][0]+len[j][1];
                        if(que[tail]>20)continue;
                        LL l=0;
                        for(int k=0;k<que[tail];++k) 
                            l=(l*P+can[k]+mod)%mod;
                        if(vis[l])continue;
                        vis[l]=1;
                        for(int k=0;k<que[tail];k++) 
                            tmp[tail][k]=can[k];
                        step[tail]=step[head-1]+1;
                        //printf("%d
    ",step[tail]);
                        tail++;    
                    }
                }
            }
        }
    }
    int main () {
        scanf("%s%s",s,t);
        len1=strlen(s);
        len2=strlen(t);
        while(scanf("%s%s",tf[cnt][0],tf[cnt][1])!=EOF) {
            len[cnt][0]=strlen(tf[cnt][0]);
            len[cnt][1]=strlen(tf[cnt][1]);
            cnt++;
        }
        //printf("%d
    ",cnt);
        if(!bfs())
        printf("NO ANSWER!
    ");
        return 0;
    }
  • 相关阅读:
    表单提交原来是这句 return啊
    jquery控制table列.rar
    iframe 大数据量传参 本地能调用远程页面 不存在跨域问题 js组件调用原理
    public string GetUrltoHtml(string Url)
    一个xml转html的小程序 别人一个毕业设计【难度:简单】
    铭万轮换广告组件
    C#操作 ini文件类【转】
    捕捉浏览器的刷新与关闭 兼容ie、ff(火狐)
    列表循环 float:left marginright:10px 如何对齐右边距小技巧
    access 双表连接代码
  • 原文地址:https://www.cnblogs.com/sssy/p/7718372.html
Copyright © 2020-2023  润新知