2018桂林J - Stone Game(博弈)

传送门


题目

爱丽丝和鲍勃总是在玩游戏!今天的游戏是依次从石堆中取出石头。 有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<bits/stdc++.h>
#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: Alice\n", i);
		else printf("Case %d: Bob\n", i);
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值