专栏文章

AtCoder Beginner Contest 384 A~D

题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq1ecdo
此快照首次捕获于
2025/12/03 21:22
3 个月前
此快照最后确认于
2025/12/03 21:22
3 个月前
查看原文

A - aaaadaa


题目

给你一个长度为 NN 的字符串 SS,和两个小写英文字母 c1c_1c2c_2
请找出并用 c2c_2 替换 SS 中每个不是 c1c_1 的字符后得到的字符串。

代码

CPP
#include <bits/stdc++.h>

using namespace std;

int n;
char c1, c2;
string s;

int main()
{
	scanf("%d", &n);
	cin >> c1 >> c2 >> s;
	for (int i = 0; i < s.length(); i ++ )
	{
		if (s[i] == c1)
			cout << s[i];
		else
			cout << c2;
	}
	return 0;
}

B - ARC Division


题目

AtCoder 常规赛(ARC)分为两个组别。
  • 在 ARC Div.1 中,比赛开始时评分在 1600160027992799(含)之间的参赛者将接受评分更新。
  • 在 ARC Div.2 中,比赛开始时评分在 1200120023992399(含)之间的参赛选手须更新评分。
高桥决定参加 NN 场 ARC。
他的初始评分为 RR
i (1iN)i \ (1 \le i \le N) 次 ARC 是 ARC Div.DiD_i,他在比赛中的表现用整数 AiA_i 表示。
如果他在第 ii 场 ARC 中评分更新了,那么 TT 就是他在比赛开始时的评分。那么在比赛结束后,他的评分就变成了 T+AiT+A_i
如果他没有更新评分,那么他的评分就不会改变。
ARC 的评分更新是在比赛结束后立即进行的,他在下一场比赛中是否要更新评分取决于他上一场更新后的评分。
求在完成 NN 场 ARC 之后他的评分。
除了这 NN 场 ARC 之外,他没有参加任何比赛。他的评分也没有其他方面的变化。

代码

CPP
#include <bits/stdc++.h>

using namespace std;

int n, r, d, a;

int main()
{
	scanf("%d %d", &n, &r);
	for (int i = 0; i < n; i ++ )
	{
		scanf("%d %d", &d, &a);
		if (d == 1)
		{
			if (1600 <= r && r <= 2799)
				r += a;
		}
		else
		{
			if (1200 <= r && r <= 2399)
				r += a;
		}
	}
	cout << r << '\n';
	return 0;
}

C - Perfect Standings


题目

Takahashi 决定举办一次编程竞赛。
竞赛包含五道题目:A、B、C、D、E,得分分别为 aabbccddee
共有 3131 名参赛者,每人都至少解答了一道题目。
更具体地说,对于字符串 ABCDE 的每个非空子序列(不一定连续),都有一个以该子序列命名的参赛者,他解答了与其名字中字母对应的题目,而没有解答其他题目。
例如,参赛者 AA 只解答了题目 A,参赛者 BCEBCE 解答了题目 B、C 和 E。
按得分从大到小的顺序打印参赛者的姓名。参与者获得的分数是他们所解决问题的分数的总和。
如果两个参与者获得的分数相同,则首先打印名字在字典中较小的参与者。

思路

其实题目说的很清楚了,且五个题目的分数是逐渐递增(可能相等)的。
由于排名中人的名字和数量是不变的,所以我们可以借助结构体打表,存储所有人的名字,以及这个人对应的分数。
这时,如何对数据进行排序呢?
我们先考虑根据分数排序,如果分数相同,则根据字典序排序。排序完成后,按排序顺序直接输出名字即可。

代码

CPP
// LUOGU_RID: 206168283
#include <bits/stdc++.h>

using namespace std;
int a, b, c, d, e;
string names[] = {"ABCDE", "BCDE", "ACDE", "ABDE", "ABCE", "ABCD", "CDE", "BDE", "ADE", "BCE", "ACE", "BCD", "ABE", "ACD", "ABD", "ABC", "DE", "CE", "BE", "CD", "AE", "BD", "AD", "BC", "AC", "AB", "E", "D", "C", "B", "A"}; // 打表存储名字

// 结构体存储信息
struct node
{
	string name;
	int val;
} p[110];

bool cmp(node a, node b) // cmp():告诉 sort() 排序方法
{
	if (a.val != b.val) // 先根据分数排序
		return a.val > b.val;
	if (a.val == b.val) // 后根据字典序排序
		return a.name < b.name;
}

int main()
{
	scanf("%d %d %d %d %d", &a, &b, &c, &d, &e); // 输入
	for (int i = 0; i <= 30; i ++ ) // 将数据计算并存入结构体
	{
		p[i + 1].name = names[i];
		for (int j = 0; j < names[i].size(); j ++ )
		{
			if (names[i][j] == 'A')
				p[i + 1].val += a;
			else if (names[i][j] == 'B')
				p[i + 1].val += b;
			else if (names[i][j] == 'C')
				p[i + 1].val += c;
			else if (names[i][j] == 'D')
				p[i + 1].val += d;
			else if (names[i][j] == 'E')
				p[i + 1].val += e;
		}
	}
	sort(p + 1, p + 32, cmp); // 排序 
	for (int i = 1; i <= 31; i ++ ) // 输出
		cout << p[i].name << '\n';
	return 0;
}

D - Repeated Sequence


题目

给你一个周期为 NN 的无穷序列 A=(A1,A2,A3,)A=(A_1,A_2,A_3, \ldots) 的前 NNA1,A2,,ANA_1,A_2, \ldots ,A_N
请判断该无穷序列是否存在和为 SS 的非空连续子序列。
这里,当每个整数 i>Ni>N 的周期为 Ai=AiNA_i=A_{i-N} 时,无穷序列 AA 的周期为 NN

思路

为了模拟题目中无限的这个定义。我们可以让数量 nn 变成 2×n2 \times n
此时我们我们只需开一个队列,维护当前的区间和,设为 valval
如果 valvalss 相等,就直接输出。
否则调节左右端点就行。如果小,右端点右移,否则左端点右移就行了。

代码

CPP
#include <bits/stdc++.h>

using namespace std;

long long n, s, a[400010], sum, val;
queue<long long> stk;

int main()
{
	scanf("%lld %lld", &n, &s);
	for (long long i = 1; i <= n; i ++ )
	{
		scanf("%d", &a[i]);
		sum += a[i];
		a[i + n] = a[i];
	}
	s %= sum;
	for (long long i = 1; i <= n * 2; i ++ )
	{
		while (val > s)
		{
			val -= stk.front();
			stk.pop();
		}
		if (val == s)
		{
			puts("Yes");
			return 0;
		}
		val += a[i];
		stk.push(a[i]);
	}
	puts("No");
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...