题目地址:http://hihocoder.com/problemset/problem/1264

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

我们说两个字符串是非常相似的,当且仅当它们的编辑距离小于等于1.

现在我们有两个字符串A和B, 每个单位时间你可以交换字符串A的相邻的两个字符.

问最少需要多少时间,你可以让A和B变得非常相似?保证存在一种这样的方案.

输入

第一行一个字符串,表示A.

第二行一个字符串,表示B.

所有字符串都仅有英文小写字母组成.

A和B的长度都不超过100.

输出

一行表示最少需要的时间.

样例输入

nwlrb
rclwnb

样例输出

6

解题思路

首先要搞清楚什么叫“编辑距离”。编辑距离(Edit Distance)是指两个字串之间,由一个字串变成另一个字串所需要的最少编辑操作次数。编辑操作包括三种:将一个字符替换为另一个字符、插入一个字符、删除一个字符。

由题目要求知道,这样方案一定存在,那么A、B两个字串要么长度相同,要么长度相差1。分类讨论,设n为A串的长度,m为B串的长度,A串最后变成C串,C串与B串的编辑距离<=1。

当n==m时,这时C串长度与A、B串一样,所以与B串要么一样,要么有一个字母不一样;当n==(m+1)时,表示C串要添加一个字符得到B串,同样也是B串删除一个字符得到C串;当(n+1)==m时,表示C串要删除一个字符得到B串,同样B串添加一个字符也可以得到C串。

现在再考虑A串怎么变成C串的。题目给出的对A串的操作只有交换两个相邻的字符,由优化思想可以知道,如果两个相邻的字符是相同的,则没有必要交换,所以说相同的字符之间的相对顺序是不会改变的,于是当C串固定时,A串变为C串的一一对应关系是确定的,也就是说A串中第k个字母a一定变到C串种第k个字母a的位置上。这样问题就转换为求逆序对数量的问题了。

思路比较清楚了,如何实现呢?我们可以枚举与B串编辑距离<=1的C串,第一种情况时间复杂度为O(n),后两种情况时间复杂度为O(n^2)。(后两种似乎可以用链表的形式优化为O(n),时间限制不苛刻,这里没有过多考虑)再计算A串到C串的交换次数,即逆序对的数量,时间复杂度为O(n^2)。

附:C++代码

 1 #include <iostream>
2 #include <cstdio>
3 #include <vector>
4 #include <algorithm>
5 #include <cstring>
6
7 using namespace std;
8 #define MaxN 120
9 #define INF 1e9
10
11 int n, m, Last[MaxN];
12 char A[MaxN], B[MaxN], C[MaxN];
13
14 vector <int> Pos[30];
15
16 int Dis()
17 {
18 int i, j, x;
19 for(i = 0; i < 26; i++)
20 Pos[i].clear();
21 for(i = n; i > 0; i--)
22 Pos[C[i] - 'a'].push_back(i);
23 for(i = 1; i <= n; i++)
24 {
25 x = A[i] - 'a';
26 if(Pos[x].size() == 0)
27 return INF;
28 else
29 {
30 Last[i] = Pos[x][Pos[x].size() - 1];
31 Pos[x].pop_back();
32 }
33 }
34 int Ans = 0;
35 for(i = 1; i <= n; i++)
36 for(j = i + 1; j <= n; j++)
37 if(Last[i] > Last[j])
38 Ans++;
39 return Ans;
40 }
41
42 int main()
43 {
44 int i, j, Ans = INF;
45 scanf("%s", A + 1);
46 scanf("%s", B + 1);
47 n = strlen(A + 1);
48 m = strlen(B + 1);
49 if(n == m)
50 {
51 memcpy(C, B, sizeof(B));
52 for(i = 1; i <= n; i++)
53 {
54 for(j = 0; j < 26; j++)
55 {
56 C[i] = 'a' + j;
57 Ans = min(Ans, Dis());
58 }
59 C[i] = B[i];
60 }
61 }
62 else if(n == (m + 1))
63 {
64 for(i = 0; i <= m; i++)
65 {
66 for(j = 1; j <= i; j++)
67 C[j] = B[j];
68 for(j = i + 1; j <= m; j++)
69 C[j + 1] = B[j];
70 for(j = 0; j < 26; j++)
71 {
72 C[i + 1] = 'a' + j;
73 Ans = min(Ans, Dis());
74 }
75 }
76 }
77 else
78 {
79 for(i = 1; i <= m; i++)
80 {
81 for(j = 1; j < i; j++)
82 C[j] = B[j];
83 for(j = i + 1; j <= m; j++)
84 C[j - 1] = B[j];
85 Ans = min(Ans, Dis());
86 }
87 }
88 printf("%d", Ans);
89 return 0;
90 }

[题解]hihoCoder挑战赛18——题目1 神奇字符串的更多相关文章

  1. hihoCoder挑战赛11.题目4 : 高等理论计算机科学(LCA)

    clj在某场hihoCoder比赛中的一道题,表示clj的数学题实在6,这道图论貌似还算可以... 题目链接:http://hihocoder.com/problemset/problem/1167 ...

  2. hihoCoder挑战赛28 题目2 : 二进制翻转

    题目2 : 二进制翻转 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 定义函数 Rev(x) 表示把 x 在二进制表示下翻转后的值 例如: Rev(4)=1,因为 4 ...

  3. hihoCoder挑战赛27题目一 福字 (dp)

    题目: 一个n × n的矩阵,其中每个位置都是一个非负整数. 一个福字被定义成是大小为 k 的正方形,满足其中的每个位置上的数都恰好比他的左边的那个和上边的那个大1(如果左边或上边的那个不存在的话就无 ...

  4. hihoCoder挑战赛28 题目3 : 树的方差

    题目3 : 树的方差 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 对于一棵 n 个点的带标号无根树,设 d[i] 为点 i 的度数. 定义一棵树的方差为数组 d[1. ...

  5. hihoCoder挑战赛28 题目1 : 异或排序

    题目1 : 异或排序 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个长度为 n 的非负整数序列 a[1..n] 你需要求有多少个非负整数 S 满足以下两个条件: ...

  6. hihoCoder挑战赛23

    hihoCoder挑战赛23 A.Emulator 题意 给一张图,有\(N(N \le 300)\)个点, 给出任意两点之间的最短路. 求最多可以去掉多少条边,使得任意两点的最短路长度不变. 思路 ...

  7. [LeetCode] Magical String 神奇字符串

    A magical string S consists of only '1' and '2' and obeys the following rules: The string S is magic ...

  8. Wannafly挑战赛18 E 极差(线段树、单调栈)

    Wannafly挑战赛18 E 极差 题意 给出三个长度为n的正整数序列,一个区间[L,R]的价值定义为:三个序列中,这个区间的极差(最大值与最小值之差)的乘积. 求所有区间的价值之和.答案对\(2^ ...

  9. Leetcode 481.神奇字符串

    神奇字符串 神奇的字符串 S 只包含 '1' 和 '2',并遵守以下规则: 字符串 S 是神奇的,因为串联字符 '1' 和 '2' 的连续出现次数会生成字符串 S 本身. 字符串 S 的前几个元素如下 ...

随机推荐

  1. HDC2021技术分论坛:组件通信、硬件池化,这些创新技术你get了吗?

    作者:ligang 华为分布式硬件技术专家,sunbinxin 华为应用框架技术专家 HarmonyOS是一款全新的分布式操作系统,为开发者提供了元能力框架.事件通知.分布式硬件等分布式技术,使能开发 ...

  2. 【解决了一个小问题】golang go.mod中多了一个斜杠导致replace无效

    replace github.com/sxxx/common_lib/src/ => ../../common_lib/src 修改成 replace github.com/sxxx/commo ...

  3. opencv 4.0 + linux + cuda静态编译

    #下载最新的opencv git clone "https://github.com/opencv/opencv.git" git clone "https://gith ...

  4. 集合框架-工具类-Collections-折半最值

    1 package cn.itcast.p2.toolclass.collections.demo; 2 3 import java.util.ArrayList; 4 import java.uti ...

  5. 聊一聊如何用C#轻松完成一个SAGA分布式事务

    背景 银行跨行转账业务是一个典型分布式事务场景,假设 A 需要跨行转账给 B,那么就涉及两个银行的数据,无法通过一个数据库的本地事务保证转账的 ACID ,只能够通过分布式事务来解决. 市面上使用比较 ...

  6. python中True和False

    python中只有0代表False,只有1代表True,注意只有!! if x: print('True') 只要x是非零数值.非空字符串.非空list等,就判断为True,否则为False.

  7. python11day

    昨日回顾 函数的参数: 实参角度:位置参数.关键字参数.混合参数 形参角度:位置参数.默认参数.仅限关键字参数.万能参数 形参角度参数顺序:位置参数,*args,默认参数,仅限关键字参数,**kwar ...

  8. 学习MyBatis必知必会(6)~Mapper基础的拓展

    一.typeAlias 类型别名[自定义别名.系统自带别名] 1.类型别名:为 Java 类型设置一个缩写名字. 它仅用于 XML 配置,意在降低冗余的全限定类名书写 2.配置自定义别名: (1)方式 ...

  9. webpack学习:uni运行时代码解读一 (页面初始化加载)

    uni的vue代码是如何在微信小程序里面执行的,对此比较感兴趣所以去调试学习了一波. 准备工作 // 在vue.config.js里打开非压缩的代码 module.exports = { config ...

  10. 使用Docker快速搭建Halo个人博客到阿里云服务器上[附加主题和使用域名访问]

    一.前言 小编买了一个服务器也是一直想整个网站,一直在摸索,看了能够快速搭建博客系统的教程.总结了有以下几种方式,大家按照自己喜欢的去搭建: halo wordpress hexo vuepress ...