zoukankan      html  css  js  c++  java
  • 【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代码
  • 相关阅读:
    从一个表格文件中录入信息,进行计算后,在文件中输出这个表格
    求一个字符串的最小正周期
    算法竞赛入门例题3-5生成元
    算法竞赛入门经典 例题3-4 猜数字游戏的提示
    回文词
    WERTYU找不出不能输出空格的原因SSSSSSSSSSSSS
    DAY 106 ES介绍
    DAY 105 redis集群搭建
    DAY 104 redis高级02
    DAY 103 redis高级01
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9749518.html
Copyright © 2011-2022 走看看