[COGS 0065][NOIP 2002] 字串变换

65. [NOIP2002] 字串变换

★★   输入文件:string.in   输出文件:string.out   简单对比
时间限制: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

 依然是大力暴搜...

单向 $BFS$ 的话开一个队列, 先把原串怼进去, 然后每次取队首字符串并尝试应用变换规则. 每应用成功一个变换后将变换后的字符串再怼回队列里. 一直重复直至变换得到待求串或者队列为空. 如果队列为空则说明不存在解. 用 $STL$ 里的 $std::string,std::pair,std::map$ 食用即可.

双向 $BFS$ 的话就从两端对称搜索, 但是深度限制在 $10$ 以内可能并不会显得多快OwO...

附双向 $BFS$ 的参考实现:

GitHub

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <cstdlib>
 8 #include <iostream>
 9 #include <algorithm>
10 
11 typedef std::pair<std::string,int> pr;
12 
13 int n;
14 int m;
15 int ans;
16 std::string from,to;
17 std::queue<pr> q1,q2;
18 std::string transform[10][2];
19 std::map<std::string,int> m1,m2;
20 std::pair<std::string,int> p1,p2;
21 
22 bool Search();
23 void Initialize();
24 std::string Replace(std::string,int,int,std::string);
25 
26 int main(){
27     Initialize();
28     if(Search())
29         std::cout<<ans<<std::endl;
30     else
31         std::cout<<"NO ANSWER!"<<std::endl;
32     return 0;
33 }
34 
35 bool Search(){
36     int len,lenp;
37     while((!q1.empty())&&(!q2.empty())){
38         p1=q1.front();
39         len=p1.first.size();
40         for(int i=0;i<len;i++){
41             for(int j=0;j<m;j++){
42                 lenp=transform[j][0].size();
43                 if(i+lenp<=len&&p1.first.compare(i,lenp,transform[j][0])==0&&m1.count(Replace(p1.first,i,lenp,transform[j][1]))==0){
44                     p2.first=Replace(p1.first,i,lenp,transform[j][1]);
45                     p2.second=q1.front().second+1;
46                     if(p2.second>10)
47                         return false;
48                     m1[p2.first]=p2.second;
49                     q1.push(p2);
50                     if(m2.count(p2.first)){
51                         ans=p2.second+m2[p2.first];
52                         return true;
53                     }
54                 }
55             }
56         }
57         q1.pop();
58         p1=q2.front();
59         len=p1.first.size();
60         for(int i=0;i<len;i++){
61             for(int j=0;j<m;j++){
62                 lenp=transform[j][1].size();
63                 if(i+lenp<=len&&p1.first.compare(i,lenp,transform[j][1])==0&&m2.count(Replace(p1.first,i,lenp,transform[j][0]))==0){
64                     p2.first=Replace(p1.first,i,lenp,transform[j][0]);
65                     p2.second=q2.front().second+1;
66                     if(p2.second>10)
67                         return false;
68                     m2[p2.first]=p2.second;
69                     q2.push(p2);
70                     if(m1.count(p2.first)){
71                         ans=p2.second+m1[p2.first];
72                         return true;
73                     }
74                 }
75             }
76         }
77         q2.pop();
78     }
79     return false;
80 }
81 
82 void Initialize(){
83     std::ios::sync_with_stdio(false);
84     std::cin.tie(0);
85     std::cin>>from>>to;
86     while(std::cin>>transform[m][0]>>transform[m][1])
87         m++;
88     m1[from]=0;
89     m2[to]=0;
90     q1.push(std::make_pair(from,0));
91     q2.push(std::make_pair(to,0));
92 }
93 
94 inline std::string Replace(std::string s, int pos,int len,std::string p){
95     return s.replace(pos,len,p);
96 }
Backup

 

posted @ 2017-08-08 19:15  rvalue  阅读(337)  评论(0)    收藏  举报