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\n",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\n",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\n",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\n",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\n",cnt);
    if(!bfs())
    printf("NO ANSWER!\n");
    return 0;
}

 

posted @ 2017-10-23 18:48  zzzzx  阅读(254)  评论(0编辑  收藏  举报