链接:https://www.nowcoder.com/acm/contest/203/G
来源:牛客网
题目描述
有n堆石子,第i堆石子有xi个。
修修和栋栋轮流取石子,每人每次需要从任意一堆石子中取走个,修修先手。无法操作的人失败。此外,如果一个人取完了一堆石子,他会立即获胜。
不巧的是,修修除了数数以外啥都不会,他希望你帮他求出他能否获胜。
修修和栋栋轮流取石子,每人每次需要从任意一堆石子中取走个,修修先手。无法操作的人失败。此外,如果一个人取完了一堆石子,他会立即获胜。
不巧的是,修修除了数数以外啥都不会,他希望你帮他求出他能否获胜。
输入描述:
第一行一个整数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; }