• 取石块 解题报告


    【问题描述】

    小 L 和小 T 进行取石块儿游戏,给定一个整数 n 表示石块儿总数,给定一个整数 k 表
    示每次最多能拿走的石块儿数量,小 L 先手,每次能拿走 1~k 个石块儿,他们中总会有一
    个人最后拿走 s 块儿石块儿,使得剩余石块儿数量为 0,则最后一个拿走剩下石块儿的人获
    胜,另外一个人失败。
    小 T 非常聪明,小 L 绝顶(秃子(逃))聪明,请判断小 T 是否能取胜。

    【输入】

    第一行一个整数 T 表示数据组数,接下来 T 行每行两个整数 n,k 意义为描述所给。

    【输出】

    对于每组数据,输出"YES"或者"NO"(不带引号),代表小 T 是否能够获胜。
    【输入输出样例】
    Input
    2
    2 1
    10 4
    Output
    YES
    YES

    题解

    倒过来想 考虑最后一步
    考虑最让小L绝望的情况,那就是无论如何都只能剩下k块以内的石头数,即k+1块,如果只剩k+1块,那么无论这个人怎么取,另外一个人都可以取完;
    也就是说,谁能让石块剩余k+1块,谁就是赢家,同理,为了让石块剩余k+1块,只要取到k+1+k+1,就一定能取到k+1;
    所以,谁拿到了k+1的倍数,谁就是赢家
    所以只要判断出n与k+1的关系,就能在开局判断结果(当然是两个人都足够聪明的情况)
    若n为k+1的倍数,先手肯定怎么都赢不了(只要后手没有飘)

    代码

    #include <cstdio>
    #define ll long long
    #define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
    using namespace std;
    inline unsigned ll read(){
    	unsigned ll 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;
    }
    unsigned ll n,k;
    
    void init(){
    	n=read(),k=read();
    }
    
    void doit(){
    	if (n-n/(k+1)*(k+1)) puts("NO");//n-n/(k+1)*(k+1)=n%(k+1),前者跑得比后者快一点点
    	else puts("YES");
    }
    
    signed main(){
    	file("tstones");
    	int T=read();
    	while (T--){
    		init();
    		doit();
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    docker镜像操作
    利用docker搭建lnmp平台
    算法导论笔记
    算法导论笔记
    VMware 安装CentOS 7 NAT模式 配置静态ip 连接外网 xshell连接虚拟机
    spring boot入门笔记(四)
    spring boot入门笔记 (三)
    spring boot入门笔记 (二)
    spring boot入门笔记 (一)
    修改request请求参数
  • 原文地址:https://www.cnblogs.com/cancers/p/11294898.html
Copyright © 2020-2023  润新知