题干:
链接:https://ac.nowcoder.com/acm/contest/327/G
来源:牛客网
一天,处女座在牛客算法群里发了一句“我好强啊”,引起无数的复读,可是处女座发现复读之后变成了“处女座好强啊”。处女座经过调查发现群里的复读机都是失真的复读机,会固定的产生两个错误。一个错误可以是下面的形式之一:
1. 将任意一个小写字母替换成另外一个小写字母
2. 在任意位置添加一个小写字母
3. 删除任意一个字母
处女座现在在群里发了一句话,他收到了一个回应,他想知道这是不是一个复读机。
输入描述:
两行
第一行是处女座说的话s
第二行是收到的回应t
s和t只由小写字母构成且长度小于100
输出描述:
如果这可能是一个复读机输出”YES”,否则输出”NO”
示例1
输入
abc
abcde
输出
YES
说明
abc->abcd->abcde
示例2
输入
abcde
abcde
输出
YES
说明
abcde->abcdd->abcde
备注:
只要能经过两步变换就从s得到t就有可能是复读机。
解题报告:
转化一下就是可编辑距离的裸题。
题目的意思是有两个错误的才输出YES,但是首先我们知道如果求出的ans=2那一定是可以的,但是对于ans=1:如果是替换,那我们可以先增加一步操作换成别的;如果是增加,那我们可以先增加一个别的然后再换成正解;如果是删除,那我们可以先把要删除的字符换成别的然后再删除。总之ans=1的我们可以增加到ans=2,也就是输出YES。ans=0的更不多说,也是输出YES。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e2 + 5;
char s[MAX],t[MAX];
ll dp[MAX][MAX];
int main() {
cin>>s+1;
cin>>t+1;
int len1 = strlen(s+1);
int len2 = strlen(t+1);
memset(dp,0x3f3f,sizeof dp);
dp[0][0]=0;
for(int i = 1; i<=len1; i++) {
for(int j = 1; j<=len2; j++) {
if(s[i] == t[j]) dp[i][j] = dp[i-1][j-1];
else {
ll tmp1 = dp[i][j] = dp[i-1][j-1]+1;//操作1
ll tmp2 = dp[i-1][j]+1;
ll tmp3 = dp[i][j-1]+1;
dp[i][j] = min(tmp1,min(tmp2,tmp3));
}
}
}
if(dp[len1][len2] <= 2) puts("YES");
else puts("NO");
return 0 ;
}