AtCoder Beginner Contest 053

pangyou3s / 2024-08-31 / 原文

A - ABC/ARC

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int x;
	cin >> x;
	if (x < 1200) cout << "ABC";
	else cout << "ARC";
	return 0;
}

B - A to Z String

从前到后找第一个 \(A\),从后到前找第一个 \(Z\) 即可。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	string s;
	cin >> s;
	int n = s.size();
	int i = 0, j = n - 1;
	while (i < n) {
		if (s[i] == 'A') break;
		i++;
	}
	while (j >= 0) {
		if (s[j] == 'Z') break;
		j--;
	}
	cout << j - i + 1;
	return 0;
}

C - X: Yet Another Die Game

参考资料

贪心
既然要求最少的轮次,那么要每一轮拿更多的分数。

怎么让每一轮的分数最大化呢?

第一轮,按照贪心的“选择目前最优”的思路,选择六分;

第二轮,继续选择目前最优,由于要翻转,不能再得到六分,这次就选择到了五分(骰子上 \(6\)\(5\) 相邻);

第三轮,又可以翻转回六分了,选择六分。

所以我们每一轮的得分为 \(6 \Longrightarrow 5 \Longrightarrow 6 \Longrightarrow 5 ...\)

如果 \(x\)\(11\) 的倍数,答案当然呼之欲出—— \(\dfrac{x}{11}\) 所以,现在我们要处理的是 \(x\)\(11\) 的倍数还差(或是多出)的一部分的处理方式

把一次 \(6\) 分 和一次 \(5\) 分看作一轮,现在如果我们按照一大轮一大轮地扔,需要扔几大轮?答案是向上取整的 \(\dfrac{x}{11}\),求出这个值以后,我们只需要再判断能不能少掷五分的那一次就好了。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	i64 x, ans = 0;
	cin >> x;
	i64 n = ceil(x / 11.0);
	ans = n * 2;
	if (n * 11 - 5 >= x) ans--;
	cout << ans;
	return 0;
}

D - Card Eater

初步想到了应该需要排序后去重,但没想到具体的做法。

排序后,由于目标是尽可能使得标号两两不同,应当尽可能删除重复的。
注意题目说的花里胡哨的,其实就是每次丢弃两张牌。这样的话,我们计算出相邻扑克牌重复的次数,如果是偶数全部删除就行。如果是奇数,还得再删一个其他的,\(\rm m\)++。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i++) cin >> a[i];
	sort(a.begin(), a.end());
	
	int m = 0;
	for (int i = 1; i < n; i++) {
		if (a[i] == a[i - 1]) m++;
	}
	if (m % 2 == 1) m++;
	cout << n - m;
 	return 0;
}