CSDN竞赛8期题解

总结

这次竞赛有挺多遗憾的地方,第二道通过了六成的用例,考试时调半天也没ac,一直以为是DP的状态划分有情况没有考虑到,直到赛后看到bug讨论才知道是后台用例字符串的长度范围是1000,题目标注的是100,这种错误不仅引起了T2T_2T2的失分,还浪费了大量时间去调试影响了后面的答题。

另一个遗憾的地方是第四道,考试时通过了八成的用例,代码逻辑没多大问题。前面题目调试花了太多时间,就没时间继续调试T4T_4T4了,赛后发现只需要多循环几次就可以AC这道题了,不得不说太亏了。

这次竞赛题目质量还是不错的,如果不考虑种种bug的话。题目由两道简单题和两道中等难度题构成,简单题原则上说是可以秒的,然而出题人可能不希望我们秒掉。比如T1T_1T1,写个hash表很快就可以解决,如果提交代码的话会发现不能ac,因为题目给的输入模板有问题,输入字符串包含空格,但是模板输入使用cin读取,如果没有怀疑输入模板,那么会在这题卡一会。再比如T3T_3T3,基础的DP题,也是可以秒的,但是输入模板读取的方格上的数字是字符串类型。本来输入模板是为了简化我们作答的,但是使用字符串的输入我们还需要逐个转化为int类型,不如自己去写输入。

忽略一些bug的话,这次的四道题有三道考察DP,T2T_2T2T4T_4T4题目还是不错的,尤其是T4T_4T4,DP加上基本的概率论知识,题目比较新颖。

题目列表

1.代写匿名信

题目描述

小Q想要匿名举报XX领导不务正业! 小Q害怕别人认出他的字迹。 他选择从报纸上剪裁下来英文字母组成自己的举报信。 现在小Q找来了报纸,和自己的举报信的Txt, 你能帮他确定一下是否能够完成匿名信吗?

分析

题目输入第一行是报纸的字符串,第二行是举报信的字符串。字符串中可能含有空格,所以作答时首先把输入模板代码里的cin换成getline,然后使用hash表统计出现过的字符,如果举报信的所有字符都出现过,输出“Yes“,否则输出”No“。

代码

#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
std::string solution(std::string words, std::string msg) {
   
   
	unordered_set<char> s;
	int n = words.size(),m = msg.size();
	for(int i = 0; i < n; i++) s.insert(words[i]);
	for(int i = 0; i < m; i++) {
   
   
		if(!s.count(msg[i])) return "No";
	}
	return "Yes";
}
int main() {
   
   
	std::string words;
	std::string msg;
	getline(cin,words);
	getline(cin,msg);
	std::string result = solution(words, msg);
	std::cout<<result<<std::endl;
	return 0;
}

2.小艺改编字符串

题目描述

已知字符串str. 添加至少多少字符可以使得str变成回文串。

分析

这题的经典做法是求出str与str逆序后字符串的LCS,将str的长度减去LCS的长度就是本题的答案,下面用另一种方式求解。

题目给的字符串长度是100100100以内,实际用例会出现100010001000以内的数据,所以DP时候数组长度要注意。

设f[i][j]表示将输入s从下标为i到j的字符通过添加字符变为回文串的最小操作次数。一般的减而治之可能不太好处理本题,需要从回文串的性质出发。输入字符串是s,添加字符后得到的回文串是t,既然t是回文串,那么只要其长度大于1,t两侧的字符一定是相同的。换而言之,如果输入s两侧的字符串相同,那么将s变成回文串的操作次数和将s去掉首尾两个字符后变成回文串的操作次数也是相同的。比如s=cabcs = cabcs=cabc,将内层ababab变成回文串可以插入一个字符aaa得到abaabaaba。而对于s而言,插入a后cabaccabaccabac也是回文的。

所以我们可以根据s[i]s[i]s[i]s[j]s[j]s[j]的字符是否相同来进行状态划分:
f[i][j]={ f[i+1][j−1],if s[i]== s[j]min(f[i+1][j],f[i][j−1])+1,if s[i]!= s[j] f[i][j]= \begin{cases} f[i+1][j-1], & \text{if $s[i]$== $s[j]$}\\ \\ min(f[i+1][j], f[i][j-1]) + 1,& \text{if $s[i]$!= $s[j]$} \end{cases} f[i][j]= f[i+1][j1],min(f[i+1][j],f[i][j1])+1,if s[i]== s[j]if s[i]!= s[j]

如果s[i]s[i]s[i]== s[j]s[j]s[j]f[i][j]=f[i+1][j−1]f[i][j] = f[i+1][j-1]f[i][

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值