洛谷 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

 

 1 /*
 2     双向bfs
 3     同时搜索 不需要剪枝
 4     巧妙利用string函数 
 5 */
 6 #include<map>
 7 #include<queue>
 8 #include<string>
 9 #include<cstdio>
10 #include<iostream>
11 #define MAXN 10
12 
13 using namespace std;
14 
15 string str[MAXN],str2[MAXN];
16 
17 string pre,last;
18 
19 int n=1;
20 
21 bool f[MAXN];
22 
23 queue<string> head,tail;
24 
25 map<string,int> visa,visb;
26 
27 inline void bfs() {
28     visa[pre]=1;visb[last]=1;
29     head.push(pre);
30     tail.push(last);
31     while(1) {
32         if(head.empty()||tail.empty()) {cout<<"NO ANSWER!"<<endl;return;}
33         string ta,tb;
34         ta=head.front();
35         tb=tail.front();
36         for(int i=1;i<=n;i++) {
37             int k=0;
38             while(ta.find(str[i],k)!=-1) {//以下函数不懂得可以自己百度 
39                 k=ta.find(str[i],k);
40                 int len=str[i].size();
41                 ta.replace(k,len,str2[i]);
42                 if(visa[ta]==0) {
43                     visa[ta]=visa[head.front()]+1;
44                     head.push(ta);
45                 }
46                 if(visb[ta]!=0) {
47                     printf("%d\n",visa[ta]+visb[ta]-2);
48                     return;
49                 }
50                 k++;
51                 ta=head.front();
52             }
53             k=0;
54             while(tb.find(str2[i],k)!=-1) {
55                 k=tb.find(str2[i],k);
56                 int len=str2[i].size();
57                 tb.replace(k,len,str[i]);
58                 if(visb[tb]==0) {
59                     visb[tb]=visb[tail.front()]+1;
60                     tail.push(tb);
61                 }
62                 if(visa[tb]!=0) {
63                     printf("%d\n",visa[tb]+visb[tb]-2);
64                     return;
65                 }
66                 k++;
67                 tb=tail.front();
68             }
69         }
70         head.pop();
71         tail.pop();
72     }
73     return;
74 }
75 
76 int main() {
77     cin>>pre>>last;
78     while(cin>>str[n]>>str2[n]){n++;}
79     n--;
80     bfs();
81     return 0;
82 }
代码

 

posted @ 2017-06-07 17:07  拿叉插猹哈  阅读(171)  评论(0编辑  收藏  举报