字串变换

原题链接:https://www.luogu.org/problem/show?pid=1032#sub

很奇怪,莫名其妙就A掉了。。。真神奇2333

洛谷红名留念。我会继续努力。

题意已经把做法写得特别露骨了。。。最小步数,最多6个变换规则。。。。广搜自不必说,不仅可以寻找解而且还能判断步数(根据广搜首解最优的性质可以得到)。

开两个数组记录串的转换关系,然后以a串(原串)为起点开始搜索,搜索目标是b串。

需要一个map记录某个串是不是被搜到过,如果已经搜过了就不再继续搜 。

我们枚举当前队列中队头那个串的每一个位置,对每一个位置枚举所有可能的转换手段,然后去尝试拼接。

拼接函数借鉴了一下楼上stdcall大爷题解的思路,对于一个试图要改变的串str,我们试图在它的第i位用第j种手段改变,首先判断是否可行,然后再逐位拼接。并且如果拼接出的串是合法的,那么我们就把这个串继续压入队列,再次搜索,中间记录一下步数step和ans。

最后输出ans时判断,如果ans超过了步数限制直接输出无解,否则输出步数。

不过我发现,ans等于0时应该也是无解,这样会导致如果用ans<=10来判断是不是超出步数会WA掉第三个点。。

参考代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <cstring>
 4 #include <queue>
 5 #include <map>
 6 #define maxn 15
 7 using namespace std;
 8 struct node{//方便搜索,也可以使用pair简化
 9     string str;
10     int step;
11 };
12 
13 string a,b;
14 string orginal[maxn];
15 string translated[maxn];
16 int n,ans;
17 map<string,int> ma;//很重要的东西,用来判重,否则会TLE在第3点和第5点
18 
19 string trans(const string &str,int i,int j){//借鉴了stdcall大爷的思想
20     string ans = "";
21     if (i+orginal[j].length() > str.length())
22         return ans;
23 
24     for (int k=0; k < orginal[j].length();k++)
25         if (str[i+k] != orginal[j][k])
26             return ans;
27 
28     ans = str.substr(0,i);
29     ans+=translated[j];
30     ans+=str.substr(i+orginal[j].length());
31     return ans;
32 }
33 
34 void bfs(){//一个平淡无奇的bfs过程
35     queue <node> q;
36     node s;
37     s.str = a;
38     s.step = 0;
39     q.push(s);
40 
41     while (!q.empty()){
42         node u = q.front();
43         q.pop();
44         string temp;
45 
46         if(ma.count(u.str) == 1) //剪枝,判断重复的路径
47             continue;
48 
49         if (u.str == b){
50             ans = u.step;
51             break;
52         }
53         ma[u.str] = 1;
54         for (int i=0;i < u.str.length();i++)//枚举当前串所有可能位置
55             for (int j=0; j<n; j++){//枚举所有可能手段
56                 temp = trans(u.str,i,j);
57                 if (temp != ""){
58                     node v;
59                     v.str = temp;
60                     v.step = u.step+1;
61                     q.push(v);
62                 }
63             }
64     }
65     if (ans > 10 || ans == 0)
66         cout << "NO ANSWER!" << endl;
67     else
68         cout << ans << endl;
69 
70 }
71 
72 int main(){
73     cin >> a >> b;
74     while (cin >> orginal[n] >> translated[n])
75         n++;
76     bfs();
77     return 0;
78 }

 

posted @ 2017-09-19 23:43  ShawnZhou_Aether  阅读(201)  评论(0编辑  收藏  举报