【AtCoder】AtCoder Grand Contest 034 题解

本文详细介绍了AtCoder Grand Contest 034的五道题目A到E的解题思路和算法实现,涉及路径分析、组合计数、二分搜索、费用流和树形DP等技术,对于提高编程竞赛能力具有参考价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【比赛链接】

【题解链接】

【A】 Kenken Race

【思路要点】

  • 首先, A A A C C C 中与 B B B D D D 中不能存在连续的两个障碍物。
  • 其次,若 D &lt; C D&lt;C D<C ,需要额外满足 B B B D D D 中存在至少一个空位两侧均为空位。
  • 时间复杂度 O ( N ) O(N) O(N)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {
    
    x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {
    
    x = min(x, y); } 
template <typename T> void read(T &x) {
    
    
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
    
    
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
    
    
	write(x);
	puts("");
}
int n, a, b, c, d;
char s[MAXN];
int main() {
    
    
	read(n), read(a), read(b), read(c), read(d);
	scanf("%s", s + 1);
	for (int i = a; i <= c - 1; i++)
		if (s[i] == '#' && s[i + 1] == '#') {
    
    
			puts("No");
			return 0;
		}
	for (int i = b; i <= d - 1; i++)
		if (s[i] == '#' && s[i + 1] == '#') {
    
    
			puts("No");
			return 0;
		}
	if (d < c) {
    
    
		bool found = false;
		for (int i = b; i <= d; i++)
			if (s[i - 1] == '.' && s[i] == '.' && s[i + 1] == '.') found = true;
		if (!found) {
    
    
			puts("No");
			return 0;
		}
	}
	puts("Yes");
	return 0;
}

【B】 ABC

【思路要点】

  • B C BC BC 看做一个整体,任何操作不会形成新的 B C BC BC ,也不会破坏任何 B C BC BC
  • 每次操作即交换一对相邻的 A A A B C BC BC ,简单统计即可。
  • 时间复杂度 O ( ∣ S ∣ ) O(|S|) O(S)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {
    
    x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {
    
    x = min(x, y); } 
template <typename T> void read(T &x) {
    
    
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
    
    
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
    
    
	write(x);
	puts("");
}
char s[MAXN];
int main() {
    
    
	scanf("%s", s + 1);
	int n = strlen(s + 1);
	ll ans = 0; int now = 0, pos = 1;
	while (pos <= n) {
    
    
		if (s[pos] == 'A') now++, pos++;
		else if (s[pos] == 'B' && s[pos + 1] == 'C') ans += now, pos += 2;
		else now = 0, pos++;
	}
	writeln(ans);
	return 0;
}

【C】 Tests

【思路要点】

  • 显然,若一场考试玩家得分高于 N P C NPC NPC ,则将其设定为 u i u_i ui ,否则设定为 l i l_i li
  • 那么,令 g o a l = ∑ i = 1 N b i l i goal=\sum_{i=1}^{N}b_il_i goal=i=1Nbili ,玩家在第 i i i 场考试得的前 b i b_i bi 分收益为 l i l_i li ,后 X − b i X-b_i Xbi 分收益为 r i r_i ri ,我们要求总收益大于等于 g o a l goal goal
  • 二分答案,考虑计算学习 T T T 小时可以获得的收益。
  • 注意到 u i ≥ l i u_i\geq l_i uil
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值