【NOIP2002】字串变换

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1032


 

调试了好久,看出我代码能力不行了。。。

这道题几乎是裸的BFS,定义状态(s,step)表示已处理好的字符串是s,经过了step步,然后每次枚举可进行的变换,一直搜下去。大体思路很好想,但是具体实现却并不是随随便便的。BFS时需要注意,在s中不一定只出现一次a[i],但如果每次确保只举出不重复的一个a[i],就会有超时的风险。我们发现,有很多b[i]和a[j]是相同的,因此可以把他们合并,但合并后步骤数会变,而且放在结尾的串不可以在A中出现,同时,因为步骤数变了,并不能保证步骤数相同的点靠在一起。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string>
 4 #include <queue>
 5 
 6 using namespace std;
 7 
 8 int next, st[10], match[10];
 9 string A, B, a[10], b[10], ans;
10 
11 struct node {
12     string s;
13     int step;
14     node(string s, int step) : s(s), step(step) {}
15 };
16 
17 queue<node> q;
18 
19 inline void change(string s1, string s2, string s3) {
20     int i, j, l2 = s2.length();
21     for (i = next; s1[i]; ++i) {
22         for (j = 0; s2[j]; ++j) if(s1[i + j] != s2[j]) break;
23         if (j == l2) break;
24     }
25     ans = "";
26     if (j == l2) {
27         next = i + 1;
28         for (int k = 0; k < i; ++k)
29             ans += s1[k];
30         ans += s3;
31         for (int k = i + l2; s1[k]; ++k)
32             ans += s1[k];
33     } else ++next;
34 }
35 
36 inline int bfs() {
37     q.push(node(A, 0));
38     while(!q.empty()) {
39         string s = q.front().s;
40         int step = q.front().step, l = s.length();
41         q.pop();
42         for (int i = 1; i<=6; ++i) {
43             if (a[i] == "") continue;
44             for (next = 0; next < l;) {
45                 change(s, a[i], b[i]);
46                 if (ans == "") continue;
47                 if (ans == B) return step + st[i];
48                 if (step + st[i] >= 10) continue;
49                 //注意这里,因为经过压缩,不一定层数相同的在一起 
50                 q.push(node(ans, step + st[i]));
51             }
52         }
53     }
54     return -1;
55 }
56 
57 int main() {
58     cin >> A >> B;
59     int which = 1;
60     string in;
61     while (cin >> in) {
62         if (which % 2) a[(which + 1) / 2] = in;
63         else b[which / 2] = in;
64         ++which;
65     }
66     for (int i = 1; i <= 6; ++i)
67         if (a[i] != b[i]) st[i] = 1;
68     for (int i = 1; a[i] != ""; ++i) {
69         next = 0;
70         change(A, a[i], b[i]);
71         if (ans != "") match[i] = 1;
72         if (!match[i]) for (int j = 1; a[j] != ""; ++j) {
73             if (i != j && b[i] == a[j] && !match[j])
74                 b[i] = b[j], a[j] = "", ++st[i]; 
75         } //要被合并到结尾的串不可以在A中出现 
76     }
77     int out = bfs();
78     if (out != -1) printf("%d", out);
79     else printf("NO ANSWER!");
80     return 0;
81 }
AC代码

 

posted @ 2018-10-07 10:33  Mr^Kevin  阅读(107)  评论(0编辑  收藏  举报