1 条题解

  • 0

    题意分析

    1. 游戏规则
      • 两人轮流选择最多MM个足球,将其向球门方向射出。
      • 每个足球只能滚动整数倍的周长(2πR2\pi R的整数倍),且射程不超过LL厘米。
      • 无法操作者输,Alice先手。
    2. 关键限制
      • 每次射球后,足球与球门的距离必须减少k×2πRk \times 2\pi Rkk为正整数),且总减少量L\leq L

    解题思路

    1. 问题转化
      • 将每个足球的初始距离S(i)S(i)转化为“可操作次数”:计算每个S(i)S(i)最多可被2πR2\pi R整除的次数C(i)=S(i)2πRC(i) = \lfloor \frac{S(i)}{2\pi R} \rfloor
      • 2πR>S(i)2\pi R > S(i),则C(i)=0C(i)=0(无法操作)。
    2. 博弈模型
      • 转化为取石子游戏:每堆石子数为C(i)C(i),每次可选取最多MM堆,每堆至少取11颗石子。
      • 当所有C(i)C(i)均为00时当前玩家输。
    3. 胜负判定
      • 若所有C(i)C(i)异或和(NIM和)非零且先手可强制对手进入必败态,则Alice胜;否则Bob胜。

    实现步骤

    1. 预处理
      • 计算每个足球的可操作次数C(i)=S(i)2πRC(i) = \lfloor \frac{S(i)}{2\pi R} \rfloor
      • 过滤C(i)=0C(i)=0的足球(无法操作)。
    2. 博弈分析
      • 若剩余有效C(i)C(i)数量为00,直接判Bob胜(Alice无法操作)。
      • 否则,按NIM游戏规则计算异或和,结合MM的限制判断胜负:
        • 若存在某个子集的异或和可通过MM次操作清零,则Alice胜。
    3. 输出结果
      • 根据博弈分析结果输出胜者。

    代码实现

    #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
    上传者