problem
A,BA,BA,B 在玩游戏,给定一排长度为 nnn 的数列,每个人轮流取出任意一对相邻的两个数,然后把两个数的和或者乘积放入。
TTT 组询问。每组给定 n,mn,mn,m,接下来给定长度为 nnn 的数列 aia_iai。
m=0m=0m=0 AAA 先操作,m=1m=1m=1 BBB 先操作,如果最后剩下的一个数为偶数则 AAA 获胜,否则 BBB 获胜。
两人均采用最优策略。
n≤1e5,T≤10n\le 1e5,T\le 10n≤1e5,T≤10。
solution
observation1:\text{observation1}:observation1: 整个过程只与 aia_iai 的奇偶有关。
observation2:\text{observation2}:observation2: 无论是一奇一偶 / 两奇 / 两偶,AAA 都有一种方式将这个两个数取出后放入一个偶数进去。
observation3:\text{observation3}:observation3: 基于前一个观察,可知如果最后一次操作的人是 AAA,那么他一定获胜。
observation4:\text{observation4}:observation4: AAA 一定想尽可能扔掉奇数加入偶数,BBB 一定想尽可能扔掉偶数加入奇数。
对于 AAA 不管相邻两个数的各自奇偶情况,最后一定都会选择放回去一个偶数。
对于 BBB 而言,两偶怎么操作都是偶,两奇必须乘操作才是奇,一奇一偶怎么操作都是奇。
observation5:\text{observation5}:observation5: 无论 BBB 怎么操作都不可能增加原有的奇数个数,最多保持不变。
贪心地,AAA 如果能在自己游戏轮数内将所有的奇数都扔完则必胜。
而他肯定选择一段连续的奇数操作是最有效的。
BBB 是尽量操作一奇一偶局面或者两偶局面,这样才能保证奇数个数不减少。
具体看下代码就能懂了。
code
#include <bits/stdc++.h>
using namespace std;
#define maxn 100005
int T, n, m;
int a[maxn];int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ ) scanf( "%d", &a[i] ), a[i] &= 1;if( (n - 1 & 1) ^ (m & 1) ) { puts("A"); continue; }int ans = 0;for( int i = 1;i <= n;i ++ )if( a[i] > a[i - 1] ) {int j = i;while( j <= n and a[j] ) j ++;ans += j - i + 1 >> 1;i = j - 1;}if( ans <= (n - m >> 1) ) puts("A");else puts("B");}return 0;
}