比赛链接:

https://atcoder.jp/contests/arc137/tasks

A - Coprime Pair

题目大意:

给了 \(l\)\(r\),求出 \(x\)\(y\),在满足 \(l <= x < y <= r\),且 \(gcd(x, y) = 1\) 的情况下,使得 \(y - x\) 最大。

思路:

因为最多 1500 个数中就会有一个质数,所以直接暴力搜就可以了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL l, r;
int main(){
	cin >> l >> r;
	for (LL i = r - l; i >= 0; -- i)  //枚举长度
		for (LL j = l; j + i <= r; ++ j)  //枚举起点
			if (__gcd(j, j + i) == 1){
				cout << i << "\n";
				return 0;
			}
	return 0;
}

B - Count 1's

题目大意:

给定了一个只包含 0 和 1 的序列,现在可以翻转一个连续区间的值,即将这个区间所有 0 变成 1,1 变成 0,问 1 的数量有多少种可能。

思路:

要统计出改变某一个区间最多能减少或增减多少个 1,就是求最大子段和,不过要求两次,答案就是 1 加上增加和减少的最大值就可以了。

代码:

#include <bits/stdc++.h>
using namespace std;
int n, s, ans1, ans2;
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n;
	vector <int> a(n);
	for (int i = 0; i < n; ++ i){
		cin >> a[i];
		if (!a[i]) a[i] = -1;
		s = max(s + a[i], a[i]);
		ans1 = max(ans1, s);
	}
	s = 0;
	for (int i = 0; i < n; ++ i){
		a[i] = -a[i];
		s = max(s + a[i], a[i]);
		ans2 = max(ans2, s);
	}
	cout << ans1 + ans2 + 1 << "\n";
	return 0;
}

C - Distinct Numbers

题目大意:

\(Alice\)\(Bob\) 玩游戏,有一个序列 \(A\),没人操作一次,\(Alice\) 先手操作,每次可以选择序列中最大的一个数,将其改为任意一个比自身小的非负数,但是序列中不能改为序列中已有的数,当有一个人不能操作之后,则另一人获胜,两人都足够聪明,都采取最优策略。

思路:

记最大的元素记为 \(a\),次大的记为 \(b\)
当只有一个元素可以移动,其它都已经在前面的时候,先手必胜,即满足 \(b + 2 <= a\),如果 \(b + 1 = a\) 说明 \(a\) 也不能移动了。
还有两个及以上的数要移动时,要看最大的两个数之间的关系。如果刚开始就是 \(b + 1 = a\) ,那么每次的最优决策就是将 \(a\) 移到 \(b - 1\) 的位置,因为否则的话就会让对手处在 \(b + 2 <= a\) 的状态,则自己就会输。
每个人都是最优,即每次都让 \(a = b - 1\),那这时就要看移多少次才会移动到不能移的时候,判断一下 \(a\)\(n - 1\) 的奇偶性就可以了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
int n;
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n;
	vector <int> a(n);
	for (int i = 0; i < n; ++ i)
		cin >> a[i];
	sort(all(a));
	if (a[n - 2] + 2 <= a[n - 1]) cout << "Alice\n";
	else{
		int res = ( a[n - 1] - (n - 1) ) & 1;
		if (res) cout << "Alice\n";
		else cout << "Bob\n";
	}
	return 0;
}
posted on 2022-03-22 17:05  Hamine  阅读(96)  评论(0编辑  收藏  举报