链接:https://www.nowcoder.com/acm/contest/203/G
来源:牛客网
题目描述
有n堆石子,第i堆石子有x
i个。
修修和栋栋轮流取石子,每人每次需要从任意一堆石子中取走 个,修修先手。无法操作的人失败。此外,如果一个人取完了一堆石子,他会立即获胜。
不巧的是,修修除了数数以外啥都不会,他希望你帮他求出他能否获胜。
修修和栋栋轮流取石子,每人每次需要从任意一堆石子中取走 个,修修先手。无法操作的人失败。此外,如果一个人取完了一堆石子,他会立即获胜。
不巧的是,修修除了数数以外啥都不会,他希望你帮他求出他能否获胜。
输入描述:
第一行一个整数t表示数据组数 (1 ≤ t ≤ 1000)。9
每组数据第一行三个整数n,a,b (1 ≤ n ≤ 1000,1≤ a ≤ b ≤ 10
),第二行n个整数
(1 ≤ xi
≤ 109
)。
输出描述:
每组数据输出一行一个字符串:如果修修可以获胜输出Yes,否则输出No。
示例1
输出
复制No Yes
题意 : 有 n 堆石子,石子个数是给定的,每次可以取出的石子个数是 a - b, 当一次完全取完某一堆时即代表获胜。
思路分析 :
基本就是3种情况,
1 . 当石子个数 < a 时,此时 sg 值为 0
2 . 当石子个数 >= a && <= b 时,此时直接取胜
3 . 当石子个数 > b 时,打表计算此时的 sg 值,找规律,但是要注意的是此时的后继状态是不能到达 a-b 的,因为到达就必输
代码示例 :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, a, b;
ll SG(ll x){
if (x <= b) return 0;
if (a == 1) return x%(1+b);
x -= b;
x %= (a+b);
x = x/a;
if (x <= 1) x ^= 1;
return x;
}
int main () {
ll t;
ll x;
cin >> t;
while(t--){
scanf("%lld%lld%lld", &n, &a, &b);
ll ans = 0;
ll sign = 0;
for(ll i = 1; i <= n; i++){
scanf("%lld", &x);
if (x >= a && x <= b) sign = 1;
ans ^= SG(x);
}
if (ans || sign) puts("Yes");
else puts("No");
}
return 0;
}