AtCoder Beginner Contest 271 A-E 题解

比赛链接

A - 484558

就两位,直接算。

#include<bits/stdc++.h>
using namespace std;

int n, a, b;

void print(int x) {
	if(x > 9) putchar(x - 10 + 'A');
	else putchar(x + '0');
}

int main() {
	scanf("%d", &n);
	b = n % 16;
	a = n / 16;
	
	print(a), print(b);
	
	return 0;
}

B - Maintain Multiple Sequences

用一个数组记录所有的数字,再标记好每一段的开头 st 和 结尾 ed。

对于询问,直接输出。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, q, st[N], ed[N], lin[N];

void print(int x) {
	if(x > 9) putchar(x - 10 + 'A');
	else putchar(x + '0');
}

int main() {
	scanf("%d %d", &n, &q);
	int x, y;
	for(int i = 1; i <= n; i ++) {
		scanf("%d", &x);
		st[i] = ed[i - 1] + 1, ed[i] = ed[i - 1] + x;
		for(int j = st[i]; j <= ed[i]; j ++) scanf("%d", &lin[j]);
	}
	
	while(q --) {
		scanf("%d %d", &x, &y);
		printf("%d\n", lin[st[x] + y - 1]);
	}
	return 0;
}

C - Manga

贪心。

首先,因为是操作完了再开始读书,所以最多只能读到第 n 本书。

因此,编号超过 n 的书一定读不了,只能换新书,

其次,重复出现的书也不会再读,只能换新书。

为了方便指代,我们将上述两类用于换书的成为旧书,其余称为新书。

处理好旧书的数量之后,直接双指针处理,

显然,需要换新书时,旧书换一定优于用新书换,用标号大的换一定优于用标号小的换。

具体看代码。

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, a[N], tot, ans;

void print(int x) {
	if(x > 9) putchar(x - 10 + 'A');
	else putchar(x + '0');
}
bool vis[N];
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d", &a[i]);
		if(a[i] > n) tot ++;
		else if(vis[a[i]]) tot ++;
		else vis[a[i]] = 1;
	}
	int l = 1, r = n + 1;
	while(1) {
		while(vis[l]) l ++;
		while(r && !vis[r]) r --;
		if(tot >= 2) tot -= 2, vis[l] = 1;
		else {
			if(l >= r) break;
			vis[r] = 0, tot ++;
		}
	}
	printf("%d", l - 1);
	return 0;
}

D - Flip and Adjust

定义 dp[i][j] 为 前 i 位相加和为 j 的方案可行性。

显而易见,枚举第 i 位的取值,由前一位转移方程即可。

最后递归输出方案。

#include<bits/stdc++.h>
using namespace std;
const int N = 105, M = 1e4 + 5;
int n, m, a[N], b[N], dp[N][M];
bool tag[N]; 
void print(int x, int num) {
	if(!x) return;
	if(num >= a[x] && dp[x - 1][num - a[x]]) {
		tag[x] = 1;
		print(x - 1, num - a[x]);
	}
	else print(x - 1, num - b[x]);
}
int main() {
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i ++) scanf("%d %d", &a[i], &b[i]);
	dp[0][0] = 1;
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++) {
			if(j >= a[i]) dp[i][j] |= dp[i - 1][j - a[i]];
			if(j >= b[i]) dp[i][j] |= dp[i - 1][j - b[i]];
		}
	}
	if(!dp[n][m]) {
		puts("No");
		return 0;
	}
	puts("Yes");
	print(n, m);
	for(int i = 1; i <= n; i ++) {
		if(tag[i]) putchar('H');
		else putchar('T');
	}
	return 0;
}

E - Subsequence Path

维护最短路。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;
int n, m, k, a[N], b[N], c[N];
ll dis[N];
signed main() {
	scanf("%d %d %d", &n, &m, &k);
	for(int i = 1; i <= m; i ++) {
		scanf("%d %d %d", &a[i], &b[i], &c[i]);
	}
	for(int i = 2; i <= n; i ++) dis[i] = 1e18;
	int x;
	while(k --) {
		scanf("%d", &x);
		dis[b[x]] = min(dis[b[x]], dis[a[x]] + c[x]);
	}
	if(dis[n] == 1e18) puts("-1");
	else printf("%lld", dis[n]);
	return 0;
}

越来越敷衍了,都是些不值钱的遗产罢了

posted @ 2023-02-28 21:43  Spring-Araki  阅读(19)  评论(0编辑  收藏  举报