• 石子博弈


    链接:https://www.nowcoder.com/acm/contest/203/G
    来源:牛客网

    题目描述

    有n堆石子,第i堆石子有xi个。
    修修和栋栋轮流取石子,每人每次需要从任意一堆石子中取走个,修修先手。无法操作的人失败。此外,如果一个人取完了一堆石子,他会立即获胜。
    不巧的是,修修除了数数以外啥都不会,他希望你帮他求出他能否获胜。

    输入描述:

    第一行一个整数t表示数据组数 (1 ≤ t ≤ 1000)。
    每组数据第一行三个整数n,a,b (1 ≤ n ≤ 1000,1≤ a ≤ b ≤ 10
    9
    ),第二行n个整数
     (1 ≤ x
    i
     ≤ 10
    9
    )。

    输出描述:

    每组数据输出一行一个字符串:如果修修可以获胜输出Yes,否则输出No。
    示例1

    输入

    复制
    2
    1 1 3
    4
    1 1 3
    6

    输出

    复制
    No
    Yes

    题意 : 有 n 堆石子,石子个数是给定的,每次可以取出的石子个数是 a - b, 当一次完全取完某一堆时即代表获胜。
    思路分析 :
      基本就是3种情况,
      1 . 当石子个数 < a 时,此时 sg 值为 0
      2 . 当石子个数 >= a && <= b 时,此时直接取胜
      3 . 当石子个数 > b 时,打表计算此时的 sg 值,找规律,但是要注意的是此时的后继状态是不能到达 a-b 的,因为到达就必输
    代码示例 :
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    ll n, a, b;
    
    ll SG(ll x){
    	if (x <= b) return 0;
    	if (a == 1) return x%(1+b);
    	
    	x -= b;
    	x %= (a+b);
    	x = x/a;
    	if (x <= 1) x ^= 1;
    	return x;
    }
    
    int main () {
    	ll t;
    	ll x;
    	
    	cin >> t;
    	while(t--){
    		scanf("%lld%lld%lld", &n, &a, &b);
    		ll ans = 0;
    		ll sign = 0;
    		
    		for(ll i = 1; i <= n; i++){
    			scanf("%lld", &x);
    			if (x >= a && x <= b) sign = 1;
    			ans ^= SG(x);		
    		}		
    		if (ans || sign) puts("Yes");
    		else puts("No");
    	}	
    	return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    你必须会的 JDK 动态代理和 CGLIB 动态代理
    Dubbo 扩展点加载机制:从 Java SPI 到 Dubbo SPI
    volatile 手摸手带你解析
    Dubbo之服务消费原理
    Dubbo之服务暴露
    ElasticSearch之映射常用操作
    Redis5新特性Streams作消息队列
    .NET 开源项目 StreamJsonRpc 介绍[下篇]
    .NET 开源项目 StreamJsonRpc 介绍[中篇]
    .NET 开源项目 StreamJsonRpc 介绍 [上篇]
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9744999.html
Copyright © 2020-2023  润新知