传送门
题目
爱丽丝和鲍勃总是在玩游戏!今天的游戏是依次从石堆中取出石头。 有n堆石头,第I堆包含A[i]块石头。
由每堆石头的数量与其邻居的不同,他们决定在不破坏财产的情况下,一次从其中一堆石头中取出一块石头(不能在拿走一块石头后,相邻的不同石头变相同)。爱丽丝先走。 拿不到石头的玩家将输掉游戏。 你应该注意到,即使是一堆0石也还是被视为一堆!
题解
只需每次判断可以拿走多少次sum,当sum是奇数,A赢,反之B赢。
1、当a[i]都小于两边,a[i]可以变成0;
2、当a[i]都大于一边,小于一边,a[i]可以变成较小的那一边+1;
3、当a[i]都大于两边,a[i]可以变成两边最大值+1;
我们只需从头开始反复多遍历几次,就得出答案。
代码
要用scanf 和printf ,不然会被卡。
#include#define ms(a) memset(a,0,sizeof(a)); typedef long long ll; using namespace std; const int N = 1e5 + 5; int a[N]; int n; ll f() { ll x=0; for (int i = 1; i <= n; i++) { int m = -1; if (a[i] > a[i - 1])m = max(m, a[i - 1]); if (a[i] > a[i + 1])m = max(m, a[i + 1]); x += a[i] - m - 1; a[i] = m + 1; } return x; } bool solve() { ll sum = 0; scanf("%d", &n); a[0] = a[n + 1] = INT_MAX; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); ll x; while (1) { x = f(); sum += x; if (!x)break; } if (sum & 1)return 1; else return 0; } int main() { int t; cin >> t; for (int i = 1; i <= t; i++) { if (solve())printf("Case %d: Alicen", i); else printf("Case %d: Bobn", i); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)