【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 }