CSDN第17次竞赛题解与总结
前言
临近期末考,博主时间较少,本文质量可能不高,请见谅。
2022/12/21 19:00~21:00 CSDN第17次竞赛开考
本场竞赛由「清华大学出版社 & CSDN」联合主办。
《算法竞赛》 本书解析了算法竞赛考核的数据结构、算法;组织了每个知识点的理论解析和经典例题;给出了简洁精要的模板代码;通过明快清晰的文字、透彻的图解,实现了较好的易读性。点击了解更多详情。
博主因为有部分细节的错误,只拿到90分,喜提帆布包
T1判断胜负
已知两个字符串A,B。 连续进行读入n次。 每次读入的字符串都为A|B。 输出读入次数最多的字符串。
分析
送分题,直接统计A,B出现的数量,最后比较输出即可
#include<bits/stdc++.h>
using namespace std;
string s[1001];
int a,b;
int main(){
int n;
cin >> n;
for(int i=1;i<=n;i++){
cin >> s[i];
if(s[i] == s[1]) a++;
else b++;
}
if(a > b) cout << s[1];
else if(a == b) cout << "dogfall";
else for(int i=2;i<=n;i++)
if(s[i] != s[1]){
cout << s[i];
return 0;
}
return 0;
}
T2买铅笔
老师需要去商店买n支铅笔作为小朋友们参加编程比赛的礼物。她发现商店一共有 3 种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起 见,P老师决定只买同一种包装的铅笔。 商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过 n 支铅笔才够给小朋 友们发礼物。 现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少 n 支铅笔最少需要花费多少钱
分析
小学数学题,总共n人,对于共a只铅笔,价值b元的一包铅笔,需要的价钱为:
⌈
n
/
a
⌉
∗
b
⌈n/a⌉*b
⌈n/a⌉∗b
比较找出最小值即可
#include<bits/stdc++.h>
using namespace std;
int n,ans=900000000;
int a[4],b[4];
int main(){
cin >> n;
for(int i=1;i<=3;i++){
cin >> a[i] >> b[i];
ans = min(ans,int(ceil(n*1.0/a[i])*b[i]));
}
cout << ans;
return 0;
}
T3拯救爱情
小艺酱走到一个花之占卜店中。 店员小Q看到小艺酱可怜的样子,允许小艺酱免费占卜一次。 花瓣占卜:
- 一瓣“在一起”,一瓣“不在一起”;开始的花瓣表示“在一起”。
- 直到最后一个花瓣落地游戏结束。
- 可以选择多朵花,选择撕一朵花就必须撕完。
分析
本题义不是很清楚,我根据样例和题意猜出了答案的构造方式
- 先将所有数加起来,记作 s u m sum sum
- 若 s u m sum sum是奇数,直接输出
- 否则答案为 s u m − 最小的奇数 sum-最小的奇数 sum−最小的奇数
- 特别的,如果花瓣没有奇数,直接输出0
不过这样做只能过70%,我也不知道哪里有问题,而且不止我一个人出现这种情况
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n,a[N],minn=100000;
long long sum;
int main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
sum += a[i];
}
if(sum % 2 == 1)
cout << sum;
else{
for(int i=1;i<=n;i++)
if(a[i] % 2 == 1)
minn = min(minn,a[i]);
if(minn == 100000) cout << 0;
else cout << sum-minn;
}
return 0;
}
T4拯救公主
在Flower Kingdom里,住着一位美丽的公主Ana,有一天Ana得了一种怪病,神医告知国王,在遥远的幽谷中有一种药
能治愈Ana, 但是神医只有一份不完整的地图,地图的描述如下:
该地图的共有3行,第一行有m列,m为奇数,第二行有m+1列,第三行有m+2列;
每一行用一个字符串表示,只有【两种字符】;‘.'表示草地,可以从它上面通过,‘*’ 表示岩石,每一行最多一个; 入口
在左上角,由于在对角线方向上,因此即使对角线两边都有岩石,但是缝隙较大,人可以通过,故人可以向八个方向行走;
真实地图是由该地图的【每一行无限循环】得到的,这种神奇的药草就生长在第x行第y列的草地上,药草可能会在岩石上;
国王决定派遣勇敢的骑士David前去寻找拯救公主的解药; 现在聪明的你是否知道David能否找到该药?
分析
本题是一道不错的思维题,由题目容易得到以下情况会无解
- 解药这格是岩石
- 在解药这列左方存在一列三行均为岩石
经测试,本题数据较水,枚举不会超时
所以我直接枚举是否存在一列全是岩石,不过似乎有小bug导致只能过90%,但我懒得再改了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T,m,x,y,z[5];
string a,b,c;
int FIND(string s){
for(unsigned int i=0;i<s.size();i++)
if(s[i] == '*') return i+1;
return 0;
}
int main(){
cin >> T;
while(T--){
cin >> m >> x >> y;
cin >> a >> b >> c;
z[1] = FIND(a);
z[2] = FIND(b);
z[3] = FIND(c);
bool flag = false;
while(z[x] < y){
if(z[1] == z[2] && z[2] == z[3]){
cout << "NO\n";
flag = true;
break;
}
z[1] += m;
z[2] += m+1;
z[3] += m+2;
if(z[2] - z[1] >= m) z[1] += m;
if(z[3] - z[1] >= m) z[1] += m;
if(z[3] - z[2] >= m+1) z[2] += m+1;
}
if(!flag)
if(z[x] != y) cout << "YES\n";
else cout << "NO\n";
else;
}
return 0;
}
最后
建议官方公布一下第三题的数据