NOIP2002 字串变换题解(双向搜索)

65. [NOIP2002] 字串变换

时间限制:1 s   内存限制:128 MB

[问题描述]

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

[输入样例]

abcd xyz
abc xu
ud y
y yz

[输出样例]

3  在这里膜拜一下wq大佬,强行bfs藐视数据,我就比较惨了,打了好几次,正着搜反着搜都会T某个点,这就比较尴尬了,于是乎,我们引进了双向搜索这个概念。  我们可以把宽搜想像为一棵树,为了方便计算,我们暂定它为二叉树好了,如果我要搜10层,我单项搜索,会有2047个节点,但如果我双向搜索,就只有63+63==126个节点了,由此可见,双向可以说是完爆单向的,何况这只是二叉树。  于是这道题在双向搜索的前提下就无比简单了,我们把A,B分别塞进两个队列,同时广搜,直到两者相遇。至于修改操作吗,string就可以搞定了。  

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<map>
  7 #include<queue>
  8 #include<string>
  9 #include<cmath>
 10 using namespace std;
 11 string a,b;
 12 string A[10],B[10];
 13 struct st{
 14     string x;
 15     int js;
 16 };
 17 int js;
 18 queue<st> q1;
 19 bool yx;
 20 int p=12345,q=10000007;
 21 unsigned long long xp[50];
 22 int fw[2][10000007];
 23 bool get_hash(st x,int be){
 24     unsigned long long has=0;
 25     for(int i=x.x.length()-1;i>=0;i--)
 26     {
 27         has=has*p+int(x.x[i]);
 28     }
 29     has%=q;
 30     if(fw[be][has])
 31         return 1;
 32     fw[be][has]=x.js;
 33     if(fw[be^1][has])
 34     {
 35         printf("%d\n",x.js+fw[be^1][has]);
 36         exit(0);
 37     }
 38         return 0;
 39 }
 40 queue<st> q2;
 41 void bfs(){
 42     while(!q1.empty()&&!q2.empty())
 43     {
 44         st aa=q1.front();
 45         q1.pop();
 46         if(aa.js>6)
 47         {
 48             yx=1;
 49             printf("NO ANSWER!\n");
 50             return;
 51         }
 52         for(int i=1;i<=js;i++)
 53         {
 54             int la=-1;
 55             for(int j=0;j<=aa.x.length();j++)
 56             {
 57                 long long t=aa.x.find(A[i],j);
 58                 if(t>=0&&t<=20&&t!=la)
 59                 {
 60                     la=t;
 61                     j=la-1;
 62                     st c;
 63                     c.x=aa.x;
 64                     c.x.replace(t,A[i].length(),B[i]);
 65                     c.js=aa.js+1;
 66                     if(c.x.length()<=20&&!get_hash(c,0)&&c.js<=10)
 67                     {
 68                         q1.push(c);
 69                     }
 70                 }
 71             }
 72         }
 73         st bb=q2.front();
 74         q2.pop();
 75         if(bb.js>6)
 76         {
 77             yx=1;
 78             printf("NO ANSWER!\n");
 79             return;
 80         }
 81         for(int i=1;i<=js;i++)
 82         {
 83             int la=-1;
 84             for(int j=0;j<=bb.x.length();j++)
 85             {
 86                 long long t=bb.x.find(B[i],j);
 87                 if(t>=0&&t<=20&&t!=la)
 88                 {
 89                     la=t;
 90                     j=la-1;
 91                     st c;
 92                     c.x=bb.x;
 93                     c.x.replace(t,B[i].length(),A[i]);
 94                     c.js=bb.js+1;
 95                     if(c.x.length()<=20&&!get_hash(c,1)&&c.js<=10)
 96                     {
 97                         q2.push(c);
 98                     }
 99                 }
100             }
101         }
102     }
103 }
104 int main(){
105     cin>>a>>b;
106     js=1;
107     while(cin>>A[js]>>B[js])
108     {
109         js++;
110     }
111     js--;
112     st xx;
113     xx.x=a;
114     xx.js=0;
115     q1.push(xx);
116     get_hash(xx,0);
117     st yy;
118     yy.x=b;
119     yy.js=0;
120     q2.push(yy);
121     get_hash(yy,1);
122     xp[0]=1;
123     for(int i=1;i<=20;i++)
124     {
125         xp[i]=xp[i-1]*p;
126     }
127     bfs();
128     if(!yx)
129         printf("NO ANSWER!\n");
130     //while(1);
131     return 0;
132 }

时间: 2024-07-30 13:45:20

NOIP2002 字串变换题解(双向搜索)的相关文章

NOIP2002 字串变换

题二 字串变换 (存盘名: NOIPG2) [问题描述]: 已知有两个字串 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’->‘x

[NOIP2002]字串变换 T2 双向BFS

题目描述 已知有两个字串  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'->

NOIP2002字串变换[BFS]

题目描述 已知有两个字串 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’ 共进行了三

[NOIP2002] 字串变换 宽搜+深度优化

这道题硬是让我用STL水过.......而且题解里说的什么双向宽搜,交替扩展............... 这道题反正,STL用就用吧,但是状态数可以卡到千亿级别,因为这个东西是阶乘扩展的,然后我们发现他的深度会极大地影响状态数,然而如果我们把深度缩小为0.5倍,那么他的状态数也就是百万级别的,所以我们可以多源搜索来进行深度优化. 由此可见多源搜索是一个方式,深度优化是一种十分有效的优化. #include <map> #include <cstdio> #include <

[NOIP2002] 提高组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.

1099 字串变换

1099 字串变换 2002年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$.A2$ 可以变换为 B2$ …. 例如:A$='abcd' B$='xyz' 变换规则为: ‘abc’->‘xu’ ‘ud’-&

洛谷OJ P1032 字串变换 解题报告

洛谷OJ P1032 字串变换 解题报告 by MedalPluS   [题目描述] 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$.A2$ 可以变换为 B2$ …. 例如:A$='abcd' B$='xyz' 变换规则为: ‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’ 则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:

codevs1099 字串变换

题目描述 Description 已知有两个字串 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’-

P1032 字串变换

蒟蒻的解题报告 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'