「解题报告」Codeforces Round #884 (Div. 1 + Div. 2) Editorial

比赛地址:Dashboard - Codeforces Round 884 (Div. 1 + Div. 2) - Codeforces

个人评价:这场是构造专场!

A. Subtraction Game#

Problem - A - Codeforces

有一堆石子(应该是石子),每次只能拿走 a 块或者 b 块,最先不能移动的人输,构造一个数 n,使得先手必输。

两种构造方法:

  1. 构造一个数 n 小于 min{a,b}

  2. 构造一个数 n(a+b)n <(a+b+min{a,b})

其实就是变相的 a + b

/*
  The code was written by yifan, and yifan is neutral!!!
 */

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

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? ~x + 1 : x;
}

int T;

void solve() {
	ll a = read<ll>(), b = read<ll>();
	cout << a + b << '\n';
}

int main() {
	T = read<int>();
	while (T --) {
		solve();
	}
	return 0;
}

B. Permutations & Primes#

Problem - B - Codeforces

给定一个整数 n,要求构造一个 1n 的排列,使得这个排列的素数值最大

素数值定义:若一个子区间的 mex 是一个质数,那么素数值加一。

mex:一个区间中最小的没有出现的非负整数,但在本题中不讨论 0,因此在本题中的含义是最小的没有出现的正整数。

构造方法:

  1. 1 放在中间。如果一个区间不包括 1,那么这个区间对素数值的贡献为 0,想让贡献最大,1 放在中间。

  2. 第一个位置放 2,最后一个位置放 3。只要包括 1,2,但不包括 3,则 mex=3,是质数;包括 1,3,但不包括 2,则 mex=2,也是质数;当同时包括 1,2,3 时,区间长度为 n,即 mex=n+1,对于所有的排列,都会有这个最大的区间,因此就可以不考虑它,即可以不考虑同时包括 1,2,3 的情况。

  3. 剩下的空位随便排

/*
  The code was written by yifan, and yifan is neutral!!!
 */

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

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? ~x + 1 : x;
}

const int N = 2e5 + 5;

int T;
int ans[N];

void work() {
	int n = read<int>();
	for (int i = 1; i <= n; ++ i) {
		ans[i] = 0;
	}
	ans[1] = 2, ans[n] = 3, ans[n / 2 + 1] = 1;
    // 这里这样写就不用特判 1 的情况了
	for (int i = 2, k = 4; i < n; ++ i) {
		if (!ans[i]) {
			ans[i] = k;
			++ k;
		}
	}
	for (int i = 1; i <= n; ++ i) {
		cout << ans[i] << " ";
	}
	putchar('\n');
}

int main() {
	T = read<int>();
	while (T --) {
		work();
	}
	return 0;
}

C. Particles#

Problem - C - Codeforces

给定一个 n 个整数(可以为负)的序列,可以从中删掉某个位置的数,然后把这个位置的左右两边的数加在一起,合成一个新的元素(两个元素合为一个,数量也减一),如果左右元素为空,就不合并。按此操作直到最后只剩一个数,求最大可能的数。

将奇数位置的数和偶数位置的数各自提取出来,可以发现,只有奇数位置的数能与奇数位置的数合并,同理,也只有偶数位置的数可以和偶数位置的数合并(后面简称奇数集和偶数集),即最后的答案一定为奇数集的和或偶数集的和。

对于负数的情况,我们总可以将负数都删去,如果存在一个负数删掉后左右两边出现了一个正数或一个负数,那么一定会使奇数集或偶数集的答案减小,至于让哪个集的和减小,哪个集的和成为答案的可能性小,就让哪个集的和减小。

对于全是负数的极端情况,输出序列的最大值即可。

/*
  The code was written by yifan, and yifan is neutral!!!
 */

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

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? ~x + 1 : x;
}

const int N = 2e5 + 5;

int n;
int a[N];

void solve() {
	n = read<int>();
	bool fg = 1;
	ll ans1 = 0, ans2 = 0;
	for (int i = 1; i <= n; ++ i) {
		a[i] = read<int>();
		fg &= (a[i] < 0);
	}
	if (fg) {
		cout << *max_element(a + 1, a + n + 1) << '\n';
		return ;
	}
	for (int i = 1; i <= n; ++ i) {
		if (i & 1) {
			ans1 += max(a[i], 0);
		}
		else {
			ans2 += max(a[i], 0);
		}
	}
	cout << max(ans1, ans2) << '\n';
	return ;
}

int main() {
	int T = read<int>();
	while (T --) {
		solve();
	}
	return 0;
}

D. Row Major#

Problem - D - Codeforces

非正解 暴力跑过去了?

构造一个字符串,长度为 n,该字符串可以一次转化成一个 r×c 的矩阵(即 r×c=n),是的矩阵中相邻元素相等的情况最少。

首先,在序列中相邻的元素不能相同,之后枚举 n 的因数,判断矩阵中上下相邻的元素是否相同即可。

/*
  The code was written by yifan, and yifan is neutral!!!
 */

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

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? ~x + 1 : x;
}

const int N = 1e6 + 5;

vector<int> y;
char s[N];
bool vis[127];

void solve() {
	y.clear();
	memset(s, '\0', sizeof s);
	int n = read<int>();
	int lim = sqrt(n);
	for (int i = 2; i <= lim; ++ i) {
		if (n % i == 0) {
			y.emplace_back(i);
			y.emplace_back(n / i);
		}
	}
	s[1] = 'a';
	for (int i = 2; i <= n; ++ i) {
		for (int j = 'a'; j <= 'z'; ++ j) {
			vis[j] = 0;
		}
		int tmp = 'a';
		vis[(int)s[i - 1]] = 1;
		while (vis[tmp])	++ tmp;
		for (int j : y) {
			if (i - j <= 0)	continue ;
			vis[(int)s[i - j]] = 1;
			while (vis[tmp]) {
				++ tmp;
			}
			if (tmp > 'z')	tmp = 'z';
		}
		s[i] = tmp;
	}
	for (int i = 1; i <= n; ++ i) {
		putchar(s[i]);
	}
	putchar('\n');
}

int main() {
	int T = read<int>();
	while (T --) {
		solve();
	}
	return 0;
}

E 往后,题解就看不懂了,就不再补了。

作者:yifan0305

出处:https://www.cnblogs.com/yifan0305/p/17546652.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载时还请标明出处哟!

posted @   yi_fan0305  阅读(269)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-07-12 「学习笔记」平衡树——splay 三
2022-07-12 「学习笔记」平衡树——splay 二
2022-07-12 「学习笔记」严格次小生成树算法(倍增)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示