• 题解 CF33B String Problem


    字符串最短路。假设输入两字符串 $s,\,t$。如果 $s$ 和 $t$ 长度不同则一定不能转换,输出 $-1$。

    随后首先使用 Floyd 算法计算出将每个字母转换成每个字母的最小代价,若无法转换则代价为 $+infty$。随后枚举 $s$ 和 $t$ 每个相同位置转换为相同字符的最小代价,若为 $+infty$ 则输出 $-1$,否则 $ ext{sum}$ 加上这个最小代价,将字符串 $s$ 当前位置改为这个字符。

    此题有两个坑点:

    • 输入中可能有重边,需要取最小而不是直接赋值。好在 CF 出题人良心,样例 $2$ 就是这种情况,若不判断是过不了的。
    • 对于 $s_i$ 和 $t_i$,不一定只有将 $s_i$ 变为 $t_i$ 和将 $t_i$ 变为 $s_i$ 才是最值,需要枚举每个字母,计算最小值。

    $ ext{Code}$:

     1 const int N = 30;
     2 const int inf = 0x3f3f3f3f;
     3 
     4 int m, sum;
     5 string s, t;
     6 int trans[N][N];
     7 
     8 int main() {
     9     memset(trans, 0x3f, sizeof trans);
    10      cin >> s >> t >> m;
    11      if(s.size() != t.size()) return puts("-1"), 0;
    12      while(m--) {
    13          char c, cc;
    14          int d;
    15          scanf(" %c %c", &c, &cc);
    16          scanf("%d", &d);
    17          To_min(trans[c - 'a' + 1][cc - 'a' + 1], d);
    18     }
    19     rep(i, 1, 26) trans[i][i] = 0;
    20     rep(k, 1, 26) {
    21         rep(i, 1, 26) {
    22             rep(j, 1, 26) {
    23                 To_min(trans[i][j], trans[i][k] + trans[k][j]);
    24             }
    25         }
    26     }
    27     rep(i, 0, s.size() - 1) {
    28         int ss = s[i] - 'a' + 1, tt = t[i] - 'a' + 1;
    29         int mn = inf, f;
    30         rep(j, 1, 26) {
    31             if(mn > trans[ss][j] + trans[tt][j]) mn = trans[ss][j] + trans[tt][j], f = j;
    32         }
    33         if(mn == inf) return puts("-1"), 0;
    34         sum += mn, s[i] = char(f - 1 + 'a');
    35     }
    36     cout << sum << endl << s << endl;
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    原始数据导入ods
    flume job
    flume拦截器
    Pandas用法总结
    NumPy用法总结
    matplotlib的使用
    【Java】Java线程中断(Interrupt)与阻塞(park)的区别
    【MySQL】MySQL中的索引原理与索引分类
    【JUC】从Lock到AQS了解Java中的锁
    【Redis】Redis 持久化之 RDB 与 AOF 详解
  • 原文地址:https://www.cnblogs.com/BreezeEnder/p/14050577.html
Copyright © 2020-2023  润新知