欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 出处不详 摆放石子

出处不详 摆放石子

2025/12/17 18:27:58 来源:https://blog.csdn.net/jiaoliao946/article/details/142122632  浏览:    关键词:出处不详 摆放石子

目录

  • 摆放石子
    • 题目描述
      • 背景
      • 输入
      • 输出
      • 数据范围
    • 题解
      • 解法
    • 打赏

摆放石子

题目描述

背景

n n n个盒子,第 i i i个盒子最多放 a i a_i ai个石子,当前盒子里的石子数为 b i b_i bi。两人轮流往盒子里放石子,且每一次放的数量不能超过当前盒子内的石子数,当有一方放不下石子时游戏结束且该方输,问先手是否能获胜

输入

  1. 第一行一个整数 T T T,表示有 T T T组数据;
  2. 对于每组数据,第一行一个整数 n n n
  3. 接下来 n n n行,每行两个整数 a i , b i a_i , b_i ai,bi

输出

对于每组数据,输出一行 Y e s Yes Yes N o No No,表示先手是否能获胜

数据范围

1 ≤ T ≤ 50 , 1 ≤ n ≤ 50 , 0 ≤ b i ≤ a i ≤ 32767 1 \le T \le 50 , 1 \le n \le 50 , 0 \le b_i \le a_i \le 32767 1T50,1n50,0biai32767

题解

解法

可以看出,该题的规则描述的是一个有向图游戏的和,其中的每个有向图游戏 G i G_i Gi为:一个能容纳 a i a_i ai个石子的盒子,已经被放入了 b i b_i bi个石子后,两人轮流放石子,每次放的石子数不能超过已有的石子数,直到放不了石子的一方输
接下来需计算出所有 S G ( G i ) SG(G_i) SG(Gi),定义一个函数 g e t S G ( a , b ) getSG(a , b) getSG(a,b)用来求容量 a a a、已放入 b b b的游戏的 S G SG SG函数值,函数中定义变量 t t t表示满足 t + t < a t + t < a t+t<a的最大整数,即 t = ( a − 1 ) > > 1 t = (a - 1) >> 1 t=(a1)>>1

  1. b > t b > t b>t时,若 b = a b = a b=a,则 S G = 0 SG = 0 SG=0,所以若 b = a − 1 b = a - 1 b=a1,则 S G = 1 SG = 1 SG=1,依此类推, S G = a − b SG = a - b SG=ab

  2. b = t b = t b=t时,必输,所以 S G = 0 SG = 0 SG=0

  3. b < t b < t b<t时,设 t ′ = ( t − 1 ) > > 1 t^{'} = (t - 1) >> 1 t=(t1)>>1

    • b > t ′ b > t^{'} b>t,则 2 b ≥ t 2b \ge t 2bt,当 b = t − 1 b = t - 1 b=t1时, 2 b = 2 t − 2 2b = 2t - 2 2b=2t2,所以 S G = m e x ( { g e t S G ( a , t ) , g e t S G ( a , t + 1 ) , ⋯ , g e t S G ( a , 2 t − 2 ) } ) = m e x ( { 0 , a − 2 t + 2 , ⋯ , a − t − 1 } ) = 1 SG = mex(\{ getSG(a , t) , getSG(a , t + 1) , \cdots , getSG(a , 2t - 2) \}) = mex(\{ 0 , a - 2t + 2 , \cdots , a - t - 1 \}) = 1 SG=mex({getSG(a,t),getSG(a,t+1),,getSG(a,2t2)})=mex({0,a2t+2,,at1})=1,当 b = t − 2 b = t - 2 b=t2时,同理可得 S G = m e x ( { g e t S G ( a , t − 1 ) , g e t S G ( a , t ) , ⋯ , g e t S G ( a , 2 t − 4 ) } ) = m e x ( { 1 , 0 , a − 2 t + 4 , ⋯ , a − t − 1 } ) = 2 SG = mex(\{ getSG(a , t - 1) , getSG(a , t) , \cdots , getSG(a , 2t - 4) \}) = mex(\{ 1 , 0 , a - 2t + 4 , \cdots , a - t - 1 \}) = 2 SG=mex({getSG(a,t1),getSG(a,t),,getSG(a,2t4)})=mex({1,0,a2t+4,,at1})=2,依此类推, S G = t − b SG = t - b SG=tb
    • b = t ′ b = t^{'} b=t S G = m e x ( { g e t S G ( a , t ′ + 1 ) , ⋯ , g e t S G ( a , 2 t ′ ) } ) = m e x ( { t − t ′ − 1 , ⋯ , t − 2 t ′ } ) = 0 SG = mex(\{ getSG(a , t^{'} + 1) , \cdots , getSG(a , 2t^{'}) \}) = mex(\{ t - t^{'} - 1 , \cdots , t - 2t^{'} \}) = 0 SG=mex({getSG(a,t+1),,getSG(a,2t)})=mex({tt1,,t2t})=0
    • b < t ′ b < t^{'} b<t,则 2 b < t 2b < t 2b<t,所以只有可能用到 g e t S G ( a , c ) ( c ≤ 2 t ′ − 2 < t ) getSG(a , c)(c \le 2t^{'} - 2 < t) getSG(a,c)(c2t2<t),又由前两类得“若 t ′ ≤ b < t t^{'} \le b < t tb<t,则 g e t S G ( a , b ) = g e t S G ( t , b ) getSG(a , b) = getSG(t , b) getSG(a,b)=getSG(t,b)”,所以此时可以将 a a a换成 t t t,求 g e t S G ( t , b ) ( b < t ′ ) getSG(t , b)(b < t^{'}) getSG(t,b)(b<t)即可

    综上, S G = g e t S G ( t , b ) SG = getSG(t , b) SG=getSG(t,b)

所以当 b ≥ t b \ge t bt时可以直接得到 S G SG SG,反之则需将 a a a换成 t t t代入递归求解
代码如下:

#include<cstdio>#define il inlineil int read() {int x = 0;char c = getchar();while(c < '0' || c > '9') c = getchar();while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();return x;
}il int getSG(int a, int b) {int t = (a - 1) >> 1; if(b > t) return a - b;if(b == t) return 0;return getSG(t, b);
}int main() {int t = read();while(t--) {int ans = 0, n = read();while(n--) {int a = read(), b = read();if(a && b && a != b) ans ^= getSG(a, b);}ans ? puts("Yes") : puts("No");}return 0;
}

打赏

制作不易,若有帮助,欢迎打赏!
赞赏码

支付宝付款码

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词