CSDN第17次竞赛题解与总结

前言

临近期末考,博主时间较少,本文质量可能不高,请见谅。

2022/12/21 19:00~21:00 CSDN第17次竞赛开考

本场竞赛由「清华大学出版社 & CSDN」联合主办。

《算法竞赛》 本书解析了算法竞赛考核的数据结构、算法;组织了每个知识点的理论解析和经典例题;给出了简洁精要的模板代码;通过明快清晰的文字、透彻的图解,实现了较好的易读性。点击了解更多详情。

博主因为有部分细节的错误,只拿到90分,喜提帆布包

T1判断胜负

已知两个字符串A,B。 连续进行读入n次。 每次读入的字符串都为A|B。 输出读入次数最多的字符串。

分析

送分题,直接统计A,B出现的数量,最后比较输出即可

#include
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/ab
比较找出最小值即可

#include
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看到小艺酱可怜的样子,允许小艺酱免费占卜一次。 花瓣占卜:

  1. 一瓣“在一起”,一瓣“不在一起”;开始的花瓣表示“在一起”。
  2. 直到最后一个花瓣落地游戏结束。
  3. 可以选择多朵花,选择撕一朵花就必须撕完。

分析

本题义不是很清楚,我根据样例和题意猜出了答案的构造方式

  • 先将所有数加起来,记作 s u m sum sum
  • s u m sum sum是奇数,直接输出
  • 否则答案为 s u m − 最小的奇数 sum-最小的奇数 sum最小的奇数
  • 特别的,如果花瓣没有奇数,直接输出0

不过这样做只能过70%,我也不知道哪里有问题,而且不止我一个人出现这种情况

#include
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
#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;
}

最后

建议官方公布一下第三题的数据

你可能感兴趣的:(算法,c++,图论)