牛客竞赛 第二天- G处女座与复读机

本文介绍了一种用于检测复读机错误的算法,通过递归方法判断两段文本是否可通过两次错误操作(字符替换、插入或删除)相互转换。算法适用于处理小规模文本,如聊天群中的消息,以判断是否为失真复读机产生的消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://ac.nowcoder.com/acm/contest/327/G
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
一天,处女座在牛客算法群里发了一句“我好强啊”,引起无数的复读,可是处女座发现复读之后变成了“处女座好强啊”。处女座经过调查发现群里的复读机都是失真的复读机,会固定的产生两个错误。一个错误可以是下面的形式之一:

  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就有可能是复读机。
一开始思考这道题觉得这道题蛮简单的,后来自己做了发现其实不是这么容易的,因为又要判断s长了或者t长了如何解决,还要判断中间有字符的替换,关键在于,如果字符被替换了,可能还是原来那个,就如同上面的例子2。
所以我就想用递归,跳过当前判断不正确的项,然后判断后面是否正确。把所有情况或在一起就好了具体代码和解释如下。

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[105], t[105];
bool find(char *s, char *t, int sum)//开始使用递归。
{
	int ss = sum;
	int l1 = strlen(s);//s的长度
	int l2 = strlen(t);//做出长度
	//cout << "L1:" << l1 << "L2:" << l2 << endl;
	//cout << "sum:" << sum;
	//测试用的懒得去看递归调用
	if (sum > 2) return false;//每次做之前判断是否超过了2  (sum)就是错误次数
	if (l1 == 1 && l2 == 0) {
		if (sum <= 1) return true;
		else return false;
	}
	if (l1 == 2 && l2 == 0) {
		if (sum == 0) return true;
		else return false;
	}
	if (l1 == 0 && l2 == 0) {
		if (sum <= 2) return true;
		else return false;
	}
	if (l1 == 0 && l2 == 1) {
		if (sum <= 1)return true;
		else return false;
	}
	if (l1 == 0 && l2 == 2) {
		if (sum == 0) return true;
		else return false;
	}//这一大段都是判断的边界条件。即万一s或t多了(即添加或者删除了)或者刚刚好只换了字母
	if (s[0] == t[0]) {  return find(s + 1, t + 1, sum); }
	//相等就直接跳过判断后面的
	if (s[0] != t[0])
	{
		ss++;//无论哪种情况,不相等总是需要加一错误次数的
		//cout << "%";
		return find(s + 1, t + 1, ss) || find(s, t + 1,ss)||find(s+1,t,ss);
		/*这里的就是所谓的或判断了,一共三种情况,t删除了一个,t增加了一个,t被替换了,
		都在里面跳过当前,或者s跳过,或者t跳过共三种情况,只要有一种情况能过就可以
		知道这是正确的了*/
	}
	return false;//都不是肯定是错的
}
int main()
{
	cin >> s >> t;//输入
	int sum = 0;//初始化
	bool a = find(s, t, sum);
	if (a) cout << "YES";//输出
	else cout << "NO";
	return 0;
	//其实以上还要个坑点就是判断两个一样的字母,万一存在被代替的情况。
	//所以就有了两个字符串如果相等长,就只需要判断sum<=2就好了。
}
//这里原题目 acd acde是不算复读机的,我把边界改了就过了但仔细思考,我觉得
//是题目的数据给的有问题,因为acd acde这种是可能是复读机的emmm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值