1 条题解
-
0
题意分析
- 游戏规则:
- 两人轮流选择最多个足球,将其向球门方向射出。
- 每个足球只能滚动整数倍的周长(的整数倍),且射程不超过厘米。
- 无法操作者输,Alice先手。
- 关键限制:
- 每次射球后,足球与球门的距离必须减少(为正整数),且总减少量。
解题思路
- 问题转化:
- 将每个足球的初始距离转化为“可操作次数”:计算每个最多可被整除的次数。
- 若,则(无法操作)。
- 博弈模型:
- 转化为取石子游戏:每堆石子数为,每次可选取最多堆,每堆至少取颗石子。
- 当所有均为时当前玩家输。
- 胜负判定:
- 若所有异或和(NIM和)非零且先手可强制对手进入必败态,则Alice胜;否则Bob胜。
实现步骤
- 预处理:
- 计算每个足球的可操作次数。
- 过滤的足球(无法操作)。
- 博弈分析:
- 若剩余有效数量为,直接判Bob胜(Alice无法操作)。
- 否则,按NIM游戏规则计算异或和,结合的限制判断胜负:
- 若存在某个子集的异或和可通过次操作清零,则Alice胜。
- 输出结果:
- 根据博弈分析结果输出胜者。
代码实现
#include<iostream> #include<algorithm> #include<string> #include<cstring> #include<cstdio> #include<cmath> #define ll long long using namespace std; int n,m,l,r; const double pi = acos(-1.0); int a[50]; int main(){ while(~scanf("%d%d%d%d",&n,&m,&l,&r)){ int k = l/(2*pi*r); for(int i=1;i<=n;i++){ scanf("%d",&a[i]),a[i]=a[i]/(2*pi*r)+1,a[i]=a[i]%(k+1); } int flag=0; while(1){ int tmp = 0; int end = 1; for(int i=1;i<=n;i++){ tmp += a[i]%2; tmp %= (m+1); a[i]/=2; if(a[i])end=0; } if(tmp){ flag=1; break; } if(end)break; } puts(flag?"Alice":"Bob"); } return 0; } //2进制下对2取余是nim博弈,对其他取余是num-k博弈
- 游戏规则:
- 1
信息
- ID
- 1316
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者