CSDN第13次竞赛题解与总结
创始人
2024-03-25 07:41:03
0

前言

2022/12/7 CSDN第13次竞赛「人民邮电出版社 & CSDN」联合主办。

本次奖品为《计算之魂》:
系统地讲解了计算机科学的精髓,不仅有助于了解计算机科学,更有助于了解 IT 产业的技术特点、培养一些特殊的思维方式、掌握信息时代特殊的做事方法。
在这里插入图片描述说实话,这本书对我这个初中未毕业的蒟蒻用处不大,我只是想拿个定制帆布包(毕竟这东西我比较缺),所以慢慢调了一个多小时,结果没想到

在这里插入图片描述既然这本书与我这么有缘,我就勉为其难的摆在书架里吃灰吧

建议

还是和上次一样的,原题太多了。
19:00我准时打开了考试,结果一看第一题——陶陶摘苹果
作为一名刷完近二十年普及组题目的蒟蒻,这不是NOIP普及组原题吗?
于是19:01爆切T1
然后一看T2,似乎在哪做过,但又想不起来。
考完后百度一查原题在这
后两题不知道是不是原题,有找到的可以评论区回复。
还有就是这可恶的360跳出一个弹窗我就随手关了一下怎么就被判切出页面。了

题解

T1陶陶摘苹果

题意

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。 现在已知 10 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

分析

签到题(毕竟是普及组第一题),这种题学过循环和条件分支的小学生都会做,搞不懂为什么那么多0分。

代码

#include
using namespace std;
int n,ans,a[20];
int main(){for(int i=1;i<=10;i++) cin >> a[i];cin >> n; n += 30;for(int i=1;i<=10;i++)ans += a[i]<=n?1:0;cout << ans;return 0;
}

T2硬币的面值

题意

小A有n枚硬币,现在要买一样不超过m元的商品,他不想被找零,同时又不想带太多的硬币,且硬币可以重复,现在已知这n枚硬币的面值,请问最少需要多少枚硬币就能组合成所有可能(即能组合成1-m任意之间的数字)的价格?

分析

吐槽

拿洛谷月赛原题真的不会被kkk告侵权吗?
虽说这是一道原题,但最让人难堪的并不是这题有多难,而是这题不给数据范围
不过我考场上写的O(nm)O(nm)O(nm)能过就说明这题并不像原题数据范围那么恶心(低情商:这题数据太水了)。
这里就用洛谷上O(nlogn)O(nlogn)O(nlogn)的算法给大家讲解,O(nm)O(nm)O(nm)的很好想这里就不提了。

思路

首先先排序。
先明确一点,如果不存在硬币面值为1则价格为1的就无法组成,直接特判No answer!!!
反之,只要有面值为1的,就能组成所有面额,这毕竟每个数都有因子1。

设当前可取[1,sum][1,sum][1,sum]的所有面额,且当前取了一个面额为 aaa 的硬币,ansansans记录答案

容易证明,当sum>a−1sum> a-1sum>a−1时,再取这枚硬币,就能取到[1,sum+a][1,sum+a][1,sum+a]的所有面额,有兴趣的读者可以自己证明

那么我们只需将sumsumsum不断加aaa,直到它大于下一枚硬币的面额,再将aaa更新
不过这样常数比较大,有可能遇到aia_iai​和ai+1a_{i+1}ai+1​相差很大的情况,比如n=1,a1=1n=1,a_1=1n=1,a1​=1,此时算法退化到O(m)O(m)O(m),导致aia_iai​持续累加,所以我们可以直接用除法算出需累加几个aaa,从而达到O(n)O(n)O(n)的复杂度

最后有一种特殊情况,就是当最后跳出循环时sum=m−1sum=m-1sum=m−1,此时应特判输出ans+1ans+1ans+1,因为还需一个1元硬币

代码

#include
#define int long long
using namespace std;
int n,m;
int a[201000];
int ans,sum;
signed main(){cin >> n >> m;for(int i=1;i<=n;i++) cin >> a[i];a[n+1] = m; sort(a+1,a+1+n);if(a[1] != 1){cout << "No answer!!!";return 0;}for(int i=1;i<=n;i++){if(sum < a[i+1]-1){int k = (a[i+1]-2-sum)/a[i]+1;sum += a[i]*k;ans += k;if(sum >= m){cout << ans;return 0;}}}cout << ans+1;return 0;
}

T3公司新表

题意

公司里为了凸显公司的特性。 安装了一个n进制表。 已知新的表的时间是”H:M”。 时间合法的定义为H<=23 &&M<=59。 时间有多少种进制定义的方式,依次打印出来。 如果有无数种解输出”-1”,不存在输出”0”。

分析

本题是一道纯模拟题,只需掌握怎么算k进制数,但细节很多,我也就调了四五十分钟
我们先考虑什么时候有无数个解,我刚开始以为只有00:00时有无数解,但实际上,因为x0=1(x≠0)x^0=1(x ≠ 0)x0=1(x​=0),所以k进制的末尾取值与k无关,这会导致类似于08:09,0B:0E这种也有无数个解,需特判
然后我们先找到 ::: 的位置,那么其左边就是题中的H,右边就是M,我们只需算出它们的值再判断是否符合题意即可
值得注意的是,我们还应考虑k的最小取值,举个例子12:23最小应是4进制,
0A:BC就至少是13进制,如果k小于这些值将发生近位,那么这个数就是不合法的
对于无解的情况,只需用一个变量记录是否有输出,若没有,就是无解

代码

分析完就容易实现了

#include
#define ll long long
using namespace std;
int c=2;
int main(){string s;cin >> s;bool flag = false;s = " "+s;unsigned int l = 0;for(unsigned int i=1;iif(s[i] == ':') l = i;else if(s[i] >= 'A') c = max(c,s[i]-'A'+11);else c = max(c,s[i]-'0'+1);}for(int i=c;i;i++){int base = 1,a = 0,b = 0;for(unsigned int j=l-1;j>=1;j--){if(isdigit(s[j])) a += base*(s[j]-'0');else a += base*(s[j]-'A'+10);base *= i;}base = 1;for(unsigned int j=s.size()-1;j>=l+1;j--){if(isdigit(s[j])) b += base*(s[j]-'0');else b += base*(s[j]-'A'+10);base *= i;}if(a//注意当a>=24或b>=60时应判为无解cout << -1;return 0;}if(a > 23 || b > 59) break;flag = true; cout << i << " ";}if(!flag) cout << 0;return 0;
}

T4小豚鼠排排坐

题意

小艺酱买了一个由一排排格子组成的小房子nm,她想让k个小豚鼠每个小豚鼠都有自己的格子。
但是为了不浪费空间,她想要最边角的一圈2
(n+m-2)每行每列的格子都有一个小豚鼠居住。
具体来说,假设这k只小豚鼠的格子坐标为(x1, y1), (x2, y2),…,(xk, yk),则需要满足存在1 小艺酱想知道自己有多少种方案安排小豚鼠。

分析

这题的题意有点乱第二段话我也看不是很懂
但一看数据范围n,m≤5n,m\le5n,m≤5这不就是一道dfsdfsdfs模板题吗
对于每一个格子,要么选,要么不选,那我们用搜索枚举所有情况,再逐一判断是否成立,时间复杂度O(2nm)O(2^{nm})O(2nm)

代码

#include
#define ll long long
using namespace std;
int n,m,k,ans;
int a[10][10];
bool chk(){//四个条件直接枚举判断bool flag = 0;for(int i=1;i<=n;i++)if(a[i][1] == 1){flag = 1;break;}if(!flag) return false;flag = 0;for(int i=1;i<=n;i++)if(a[i][m] == 1){flag = 1;break;}if(!flag) return false;flag = 0;for(int i=1;i<=m;i++)if(a[1][i] == 1){flag = 1;break;}if(!flag) return false;flag = 0;for(int i=1;i<=m;i++)if(a[n][i] == 1){flag = 1;break;}if(!flag) return false;return true;
}
void dfs(int x,int y,int z){if(z == k){ans += chk();return ;}if(x == n+1) y++,x=1;if(y == m+1) return;dfs(x+1,y,z);a[x][y] = 1;dfs(x+1,y,z+1);
}
int main(){cin >> n >> m >> k;dfs(1,1,0);cout << ans;return 0;
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...