LQ0111 异或数列博弈
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0111 异或数列博弈相关的知识,希望对你有一定的参考价值。
题目来源:蓝桥杯2021初赛 C++ A组G题
题目描述
Alice 和Bob 正在玩一个异或数列的游戏。
初始时,Alice 和Bob 分别有一个整数a 和b,初始值为0。
有一个给定的长度为n 的公共数列X1, X2, … , Xn。
Alice 和Bob 轮流操作,Alice 先手,每步可以在以下两种选项中选一种:
选项1:从数列中选一个Xi 给Alice 的数异或上,或者说令a 变为a ⊕ Xi。(其中⊕ 表示按位异或)
选项2:从数列中选一个Xi 给Bob 的数异或上,或者说令b 变为b ⊕ Xi。
每个数Xi 都只能用一次,当所有Xi 均被使用后(n 轮后)游戏结束。
游戏结束时,拥有的数比较大的一方获胜,如果双方数值相同,即为平手。
现在双方都足够聪明,都采用最优策略,请问谁能获胜?
输入格式
每个评测用例包含多组询问。询问之间彼此独立。
输入的第一行包含一个整数T,表示询问数。
接下来T 行每行包含一组询问。
其中第i 行的第一个整数ni 表示数列长度,随后ni 个整数X1, X2, … , Xni 表示数列中的每个数。
1 ≤ T ≤ 200000, 1 ≤ sum(ni) ≤ 200000, 0 ≤ Xi < 2^20
输出格式
输出T 行,依次对应每组询问的答案。
每行包含一个整数1、0 或-1 分别表示Alice 胜、平局或败。
输入样例
4
1 1
1 0
2 2 1
7 992438 1006399 781139 985280 4729 872779 563580
输出样例
1
0
1
1
问题分析
(略)
AC的C语言程序如下:
/* LQ0111 异或数列 */
#include <stdio.h>
#define N 200000
int a[N];
int judge(int cnt1, int cnt2)
if (cnt1 % 2 == 0) return 0;
if (cnt1 == 1) return 1;
if (cnt1 % 2 != 0 && cnt2 % 2 != 0) return -1;
else return 1;
int main()
int t, n;
scanf("%d", &t);
while (t--)
int sum = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
sum ^= a[i];
if (sum == 0)
printf("0\\n");
continue;
for (int i = 20; i >= 0; i--)
int cnt1 = 0, cnt2 = 0;
for (int j = 0; j < n; j++)
if ((a[j] >> i) & 1) cnt1++;
else cnt2++;
int t = judge(cnt1, cnt2);
if ( t == 0)
continue;
else
printf("%d\\n", t);
break;
return 0;
以上是关于LQ0111 异或数列博弈的主要内容,如果未能解决你的问题,请参考以下文章