problem
A , B A,B A,B 在玩游戏,给定一排长度为 n n n 的数列,每个人轮流取出任意一对相邻的两个数,然后把两个数的和或者乘积放入。
T T T 组询问。每组给定 n , m n,m n,m,接下来给定长度为 n n n 的数列 a i a_i ai。
m = 0 m=0 m=0 A A A 先操作, m = 1 m=1 m=1 B B B 先操作,如果最后剩下的一个数为偶数则 A A A 获胜,否则 B B B 获胜。
两人均采用最优策略。
n ≤ 1 e 5 , T ≤ 10 n\le 1e5,T\le 10 n≤1e5,T≤10。
solution
observation1 : \text{observation1}: observation1: 整个过程只与 a i a_i ai 的奇偶有关。
observation2 : \text{observation2}: observation2: 无论是一奇一偶 / 两奇 / 两偶, A A A 都有一种方式将这个两个数取出后放入一个偶数进去。
observation3 : \text{observation3}: observation3: 基于前一个观察,可知如果最后一次操作的人是 A A A,那么他一定获胜。
observation4 : \text{observation4}: observation4: A A A 一定想尽可能扔掉奇数加入偶数, B B B 一定想尽可能扔掉偶数加入奇数。
对于 A A A 不管相邻两个数的各自奇偶情况,最后一定都会选择放回去一个偶数。
对于 B B B 而言,两偶怎么操作都是偶,两奇必须乘操作才是奇,一奇一偶怎么操作都是奇。
observation5 : \text{observation5}: observation5: 无论 B B B 怎么操作都不可能增加原有的奇数个数,最多保持不变。
贪心地, A A A 如果能在自己游戏轮数内将所有的奇数都扔完则必胜。
而他肯定选择一段连续的奇数操作是最有效的。
B B B 是尽量操作一奇一偶局面或者两偶局面,这样才能保证奇数个数不减少。
具体看下代码就能懂了。
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;
}