比赛链接:

https://codeforces.com/contest/1634

B. Fortune Telling

题目大意:

\(Alice\)\(Bob\) 玩游戏,\(Alice\) 有一个数 \(x\)\(Bob\) 有一个数 \(x + 3\),现有 \(n\) 个数字 \(a_1,a_2,...,a_n\),它们可以用自己的数从 1 开始一直到 \(n\),和 \(a_i\) 进行异或运算或者加法运算,某个人如果可以用自己的数得到 \(y\),那么这个人就赢了,现在知道他们俩中一定有个人获胜,问是谁。

思路:

可以知道加法和异或运算对数的奇偶性的改变是一致的,举个例子,对于加法运算来说,1 + 1 = 2,1 + 0 = 1,0 + 1 = 1,0 + 0 = 0,对于异或运算 1 ^ 1 = 0,1 ^ 0 = 1,0 ^ 1 = 1,0 ^ 0 = 0。
再加上两个人初始的数奇偶性不同,又有一个人一定会获胜,所以我们只需要 \(x\) 先和序列 \(a\) 中的所有数进行加法或者异或运算,得出来的数和 \(y\) 进行奇偶性比较,如果一样,那么 \(Alice\) 获胜,反之,\(Bob\) 获胜。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL T, n, x, y, a;
void solve(){
	scanf("%lld%lld%lld", &n, &x, &y);
	for (int i = 0; i < n; ++ i)
		scanf("%lld", &a), x ^= a;
	if ((x + y) % 2 == 0) cout << "Alice\n";
	else cout << "Bob\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

D. Finding Zero

题目大意:

给定一个未知序列,其中一个元素为 0。最多进行 \(2n - 2\) 次询问,每次询问的格式为 "? i j k",会返回 \(max(i, j, k) - min(i, j, k)\) 的值,要求通过询问去找到序列中 0 的位置。
最后可以猜两个位置,输出 "! x y",若 \(a_x = 0\)\(a_y = 0\),则获胜。

思路:

官方题解的思路。
只需要找到两个可能为 0 的位置就可以。
对于 4 个元素 \(a, b, c, d\),假设 a = 0,b <= c <= d。定义 \(\overline a = max(b, c, d) - min(b, c, d)\)
可以求出:
\(\overline a = d - b\)
\(\overline b = d\)
\(\overline c = d\)
\(\overline d = c\)
可以看出,\(\overline x\) 最大的那两个不可能会是 0。于是按照这个思路,每次对四个元素判断一下,删除不可能是 0 的两个数,然后去没判断的里面加两个数进来再进行判断。
\(n\) 为偶数的时候是刚好剩下两个的,当是奇数的时候会多一个,这时候需要添加一个不在集合中的元素进来,再进行操作。

代码:

#include <bits/stdc++.h>
using namespace std;
int T, n;
void solve(){
	cin >> n;
	vector < pair < int, int> > a;
	a.push_back({0, 1});
	a.push_back({0, 2});
	for (int p = 3; p <= n;){
		a.push_back({0, p ++ });
		if (p > n){
			if (p == n + 1 && (n & 1) ){
				int k = 1;
				while ( k == a[0].second || k == a[1].second || k == a[2].second ) k ++ ;  //不在集合中
				a.push_back({0, k});
			}
			else break;
		}
		else a.push_back({0, p ++ });
		for (int i = 0; i < 4; i ++ ){
			cout << "? " << a[(i + 1) % 4].second << " " << a[(i + 2) % 4].second << " " << a[(i + 3) % 4].second << "\n";
			cin >> a[i].first;
		}
		sort(a.begin(), a.end());
		a.pop_back();
		a.pop_back();
	}
	cout << "! " << a[0].second << " " << a[1].second << "\n";
}
int main(){
	cin >> T;
	while (T -- )
		solve();
	return 0;
}
posted on 2022-03-08 17:33  Hamine  阅读(26)  评论(0编辑  收藏  举报