CSDN竞赛12期题解
创始人
2024-03-19 19:47:20
0

总结

这次竞赛还是存在些许bug,题目难度中等,没有特别难的题目,也没有送分题。被bug和一些题目的数据卡了一段时间,最终通过还是花了不少时间的。

题目列表

1.豚鼠排名榜

题目描述

已知字符A.B,C。每个字符都有自己的权值q。
现不知道权值q,只知道A,B,C的三次比较结果。

输入描述:

输入三个字符串表示三次比较的结果

输出描述:

输出结果,如果不存在输出”Impossible”

输入样例:

A

B>C

C>A

输出样例:

ACB

分析

首先,吐槽下这题的自测输入的bug,考试环境输入<<<会被自动转化为<\<<,所以你用自测输入来测试程序会一直出错,这点卡了我挺久,检查和修改了若干遍代码后,才发现自测输入有问题。貌似在评论区回复小于号也会自动转化为<\<<。

题目意思给的输入应该是ABC两两比较的结果,三次比较结果矛盾就输出”Impossible”,这里输出结果不存在我理解为是出现AA,CA,CA,C

考试时我的想法是:既然是T1,肯定是思路越简单越好,题意输出结果不存在的情况应该就是出现矛盾的情况。所以要想完整表示三个字符间的偏序关系,必然会出现一个字符大于其他两个,一个字符大于另一个,那么比字符小的字符个数依次是012,就比如用例,从小到大是ACB,那么A大于0个字符,C大于1个字符,B大于2个字符。我们遍历输入三个表达式的时候统计下每个字符大于其他字符的次数,如果最终三个字符大于其他字符的次数分别是0,1,2,结果就是合理的,否则输出”Impossible”。

代码

#include 
#include 
#include 
#include 
using namespace std;
unordered_map m;
std::string solution(std::string exp1, std::string exp2, std::string exp3) {vector t = {exp1,exp2,exp3};m['A'] = m['B'] = m['C'] = 0;for(auto x : t) {if (x[1] == '>') m[x[0]]++;else m[x[2]]++;}string res = "ABC";int cnt[3] = {0};for (auto x : m) {cnt[x.second]++;res[x.second] = x.first;}for(int i = 0; i < 3; i++) {if(cnt[i] != 1) return "Impossible";}return res;
}
int main() {std::string exp1;std::string exp2;std::string exp3;cin>>exp1;cin>>exp2;cin>>exp3;std::string result = solution(exp1, exp2, exp3);std::cout<

2.字符串转换

题目描述

已知一个字符串a,b。 字符串b中包含数量不等的特殊符号“.”,“*”(字符串存在没有特殊符号或者全由特殊符号组成的情 况)。 “.”表示该字符可以变成任意字符,“* ”表示该字符的前一个字符可以变成任意多个。 现在我们想知道b可否通过特 殊符号变成a。 a* 可以转化为a,aa,aaa,aaaa…

分析

这道题对于会做的同学很简单,可以说能做出来的肯定做过这道题,因为如果连这么经典的题都没做过,那么一般做不出来这道题,对于第一次遇见这道题的同学来说,难度还是不小的。之前写的这道题的题解AcWing 30 正则表达式匹配。

这道题与正则表达式匹配还是有点区别的,因为正则表达式匹配中*可以使得前面字符出现0次,处理起来更加复杂,而本题指出了*前面字符至少出现一次,这样处理起来就简单了。

状态表示:f[i][j]f[i][j]f[i][j]表示aaa的前iii个字符与bbb的前jjj个字符是否匹配,truetruetrue表示匹配,falsefalsefalse表示不匹配。

状态边界:f[0][0]=truef[0][0]=truef[0][0]=true表示两个字符串都是空的情况是匹配的。

状态转移方程:

  • 如果aaa和bbb的末字符是不匹配的,即a[i−1]!=b[j−1]andb[j−1]!=′.′a[i-1]!=b[j-1]\ and\ b[j-1]!='.'a[i−1]!=b[j−1] and b[j−1]!=′.′时,f[i][j]=falsef[i][j]=falsef[i][j]=false。

  • 如果aaa和bbb的末字符是匹配的,即a[i−1]==b[j−1]orb[j−1]=′.′a[i-1]==b[j-1]\ or\ b[j-1]='.'a[i−1]==b[j−1] or b[j−1]=′.′时

f[i][j]={f[i−1][j−1],if b[j−1]!= ’*’f[i−1][j]∣f[i][j−1],if b[j−1]== ’*’f[i][j]= \begin{cases} f[i-1][j-1], & \text{if\ $b[j-1]$ != '*'}\\ \\ f[i-1][j]\ |\ f[i][j-1],& \text{if\ $b[j-1]$ == '*'} \end{cases} f[i][j]=⎩⎪⎨⎪⎧​f[i−1][j−1],f[i−1][j] ∣ f[i][j−1],​if b[j−1] != ’*’if b[j−1] == ’*’​

以a=′aaaa′,b=′a∗′a='aaaa',b='a*'a=′aaaa′,b=′a∗′为例,在求状态f[4][2]f[4][2]f[4][2]时,先考虑*前面字符出现一次的情况,即f[i][j−1]f[i][j-1]f[i][j−1]状态;再考虑*前面字符出现nnn次的情况,此时如果匹配说明f[i−1][j]f[i-1][j]f[i−1][j]也是匹配的,且匹配时*前面字符出现了n−1n-1n−1次,再加上a[i−1]==b[j−1]orb[j−1]=′.′a[i-1]==b[j-1]\ or\ b[j-1]='.'a[i−1]==b[j−1] or b[j−1]=′.′的条件,足以使得f[i][j]f[i][j]f[i][j]匹配。

代码

#include 
#include 
#include 
using namespace std;
const int N = 1005;
bool f[N][N];
std::string solution(std::string a, std::string b) {int n = a.size();int m = b.size();memset(f,false,sizeof f);f[0][0] = true;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if(a[i-1]==b[j-1] || b[j-1]=='.') f[i][j] = f[i-1][j-1];else if(b[j-1]=='*') {if(b[j-2] == '.' || b[j-2] == a[i-1]) f[i][j] = f[i][j-1] | f[i-1][j];} else f[i][j] = false;}}if (f[n][m]) return "yes";else return "no";
}
int main() {std::string a;std::string b;getline(std::cin, a);;getline(std::cin, b);;std::string result = solution(a, b);std::cout<

3. 蚂蚁家族

题目描述

小蚂蚁群是一个庞大的群体,在这个蚂蚁群中有n只小蚂蚁 ,为了保证所有蚂蚁在消息传送的时候都能接收到消息,需要在他们之间建立通信关系。就是要求小蚂蚁都可以通过多只或者直接联系到其他人。
已知几条小蚂蚁之间有通信关系,请问还需要再新建至少多少条关系?

输入描述:

第一行输入整数n,m;n为小蚂蚁总数;m为关系数。(1<=n,m<=1000)
以下m行每行m对整数x,y。(代表x与y有联系)

输出描述:

输出最少需要新建关系数。

输入样例:

4 3
1 2
2 3
3 4

输出样例:

0

分析

这道题数据也卡了我不少时间,第一印象是求连通块的数量,如果有resresres个连通块,那么需要新建的关系数就是res−1res-1res−1,然后写了个dfs求出连通块的数量,很快写完,提交通过六成用例。调大数据范围依旧只通过六成用例,于是怀疑是否是TLE。想到使用并查集求解更为简单,遂又写了个并查集,求集合的个数,写完提交还是通过了六成用例。后面就暂时做T4了,好在T4比较简单,很快AC回过头再看本题。并查集没有AC说明不是TLE,有可能是蚂蚁的编号会出现大于n的情况。

图论问题一般默认节点编号在1到n之间,但是本题偏偏就卡了这点,解决办法也很简单,并查集建立集合和最后统计集合数量以最大值1000为基准,最后统计新建关系数时减去(1000 - n)即可。修改后提交成功AC。

代码

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int fa[1005];
int find(int x) {if(x!=fa[x]) fa[x] = find(fa[x]);return fa[x];
}
int main() {int n;int m;std::cin>>n;std::cin>>m;int a,b;for(int i = 1; i <= 1000; i++) fa[i] = i;for(int i = 0; i < m; i++) {cin>>a>>b;if(fa[a] !=fa[b]) {fa[find(a)] = find(b);}}set s;for(int i = 1; i <= 1000; i++) {fa[i] = find(i);s.insert(fa[i]);}int res = s.size() - 1 - (1000 - n);cout<

4.题目名称:小股炒股

题目描述

已知n天后的股票行情,现在已有的本金是m,
规定只能入手一次股票和抛售一次股票。
最大收益是?

输入描述:

第一行输入整数n,m。(1<=n<=1000,1<=m<=10000)
第二行输入n个整数表示某股票单股价格p。(1<=p<=1000)

输出描述:

输出小最大收益

输入样例:

2 4
3 7

输出样例:

8

分析

股票买卖问题有多种变形,本题之前应该没有刷到过,引入了本金这个变量,难度不大。需要用到DP的思想,但是不需要真正的去DP。设f[i]f[i]f[i]表示在第iii天卖出股票获得的最大收益,则题目的解就是max(f[i])max(f[i])max(f[i])。

既然确定了在第iii天卖出,那么还需要考虑的就是在哪一天入手,必然要在前面最低价入手才能获得最大的收益,所以需要求出第iii天前面的最低价格,平时单调栈写习惯了考试时就写了个单调栈维护,其实只需要用一个变量维护当前遍历的最小值ttt即可,只要前面的最低价ttt小于本金mmm,就可以买入,设第iii天的价格是xxx,则在第iii天卖出股票获得的最大收益是m/t∗(x−t)m / t * (x - t)m/t∗(x−t)。这里要注意可能不止买一手,应该按照最大的手数去买,才能获得最大的利润。

代码

#include 
#include 
#include 
#include 
#include 
using namespace std;
int solution(int n, int m, std::vector& vec) {int res = 0;int t = 1e9;for(auto x : vec) {if (t <= m) {int p = m / t * (x - t);res = max(res,p);}t = min(t,x);	}return res + m;
}
int main() {int n;int m;std::vector vec;std::cin>>n;std::cin>>m;std::string line_0, token_0;getline(std::cin >> std::ws,line_0);std::stringstream tokens_0(line_0);while(std::getline(tokens_0, token_0, ' ')) {vec.push_back(std::stoi(token_0));}int result = solution(n, m,vec);std::cout<

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...