题目大意

一堆石子有n个,首先第一个人开始可以去1~ ? − 1 个(就是不能取完),接下来两人轮流取石子。 每个人可取的石子数必须是一个不超过上一次被取的石子的?倍的整数,先取完的人获胜,问先手是否必胜,必败输出lose,必胜输出第一步的操作。

有多组数据,每组给出n和k


首先考虑k=1的情况

先打个小点的表

n 2 3 4 5 6 7 8 9
P/N P N P N N N P N

可以发现所有败的状态都是2的i次方

为什么呢

考虑把n进行2进制分解

当n不为2的i次方

例n=22分解后为10110

先手可以去掉最后面的一个1

由于后手取的数只能小于前个取的数的k,而k为1

这样的话后手一定不能去掉一个更高位的1,只能在后面的0中取

后手取完之后后面一定会生成至少一个新的1

前面的数值就会减少

先手就可以再通过上面的方法取最后一个1

这样到最后最后一个1就是先手的,所以必胜

而当n为2的i次方

由于题目限制不能一次性取完 所以在先手第一次取完之后

后手再按上面一种情况的方法就可必胜,先手就必败


再考虑k=2的情况

再打个表(手推)和分析k=1情况时的规律

n 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
P/N P P N P N N P N N N N P N N N N N N N P N

可以发现必败的状态为斐波那契数列上的数

因为正整数都可以用斐波那契数列上的数分解

把一个数用斐波那契数列从大到小分解

分解出的1一定不是相邻的

否则通过斐波那契数列的性质相邻的1一定可以合成更大的一个数

而在斐波那数列中 中间位置隔至少为1的两个数

大的数一定为小的数的两倍以上 所以也无法取到更大的一个1

也像k=1的情况那样 只能在后面的0中取

按照k=1的方法就可知道必胜和必败态


K为其他的情况

有了上面的规律就可以扩展到k为其它数的情况

我们需要想办法构造出适用于k的类似上面两种情况的数列

条件:

1.使小于等于n的数都能被该数列上的数分解

2.一个数的 用于分解的 从大到小的 数列上的数之间 相邻数的倍数大于k倍

这样就可以用k=1的方法解决了

那么该怎么构造呢

设我们需要构造的数列为a[ i ],当数列为长度为i时最大能合成的数为b[ i ]

我们先假设我们已经构造了i项这个数列

因为b[ i ]是此时能合成的最大的数

那么b[ i ]+1的数此时就不能合成 理所当然的a[ i+1]就需要等于b[ i ]+1

求现在最大能构造的数b[ i+1] 显然也需要用到a[ i+1]

因为需要满足分解的相邻两项的倍数大于k

设 最后一个与a[ i+1]倍数大于k的位置为j

所以b[ i+1]=b[ j ]+a[ i+1];

如果没有倍数大于k的数那么显然b[ i+1]=a[ i+1];

而在b[ i ]到b[ i+1 ]之间的数由于1到b[ j ]的数都能合成和算上a[ i+1]

所以也都能合成出来

显然因为1也需要合成

所以初始状态 a[ 0 ]=1所以直接得出b[ 0 ]=1

递推下来这样序列就可以构好了

整理一下递推的式子(i为当前要求的 j为倍数大于k的最后个位置)

1.初始状态:--a[ 0 ]=b[ 0 ]=1;

2.a的递推:---a[ i ]=b[ i-1]+1;

3.b的递推:---if(a[ j ]*k<a[ i ]) b[ i ]=b[ j ]+a[ i ];

4.-------------else b[ i ]=a[ i ];

最后在考虑怎么得出答案

1.如果n为a中的数为必败直接输出“lose”

2.否则为必胜 从大到小枚举a[ i ],n>=a[ i ]减去 记录最后一个被减的i的位置

还有些细节还是看代码吧


代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{ll s=0,r=1;char c=C;for(;c<0||c>9;c=C) if(c==-3) r=-1;for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;return s*r;
}
const int N=20000010;
int n,k,casen=1;//casen 记录当前是第几组数据
int a[N],b[N];
int main()
{int t=read();while(t--){n=read(),k=read();a[0]=b[0]=1;//初始状态 int i=0,j=0; while(n>a[i])//递推求a,b   因为还要判断n是否在数列上所以递推a到大于n为止
        {i++;a[i]=b[i-1]+1;//推a while(a[j+1]*k<a[i]) j++;//查找倍数大于k的最后一个位置 if(a[j]*k<a[i]) b[i]=b[j]+a[i];//推b  else b[i]=a[i];}printf("Case %d: ",casen++);int ans;if(n==a[i]){printf("lose\n");continue;}//必败 for(;n;i--)//必胜 找最后一个被减的i if(n>=a[i]){n-=a[i];ans=a[i];}printf("%d\n",ans);} return 0;
}

转载于:https://www.cnblogs.com/1436177712qqcom/p/10375786.html

题解 UVA1567 【A simple stone game】相关推荐

  1. 【HDU - 6237】A Simple Stone Game(贪心,思维,素因子分解,数学)

    题干: After he has learned how to play Nim game, Bob begins to try another stone game which seems much ...

  2. POJ 3922 A simple stone game(K倍减法游戏)

    题目链接:http://poj.org/problem?id=3922 题意:两人取一堆石子,石子有n个. 先手第一次不能全部取完但是至少取一个.之后每人取的个数不能超过另一个人上一次取的数的K倍.拿 ...

  3. POJ - 3922 A simple stone game(K倍博弈-斐波那契博弈进阶)

    题目链接:点击查看 题目大意:给出 n 个石子,两人轮流取石子,取到最后一个石子的人获胜,规定: 第一次取石子不能全部取完 后续取石子的数量必须不超过前一次的K倍 题目分析:大佬博客:https:// ...

  4. 2017CCPC哈尔滨 H:A Simple Stone Game

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1008&cid=784 题意: 给你n个正整数,每次可以将某个 ...

  5. HDU A simple stone game [K倍动态减法游戏]

    转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 神牛曹钦翔的论文:从"k ...

  6. leetcode 877. Stone Game | 877. 石子游戏(递归/动态规划/数学解法)

    题目 https://leetcode.com/problems/stone-game/ 题解 搜了一下 stone game,结果.. 进入正题: 一开始写了个递归,超时了.没想出怎么写 dp,看了 ...

  7. USACO 2020~2021 February Contest GOLD 题解(3)

    USACO 2020~2021 二月黄金组 题解(3) 3. Count The Cows As is typical, Farmer John's cows have spread themselv ...

  8. WHUT第九周训练整理

    WHUT第九周训练整理 写在前面的话:我的能力也有限,错误是在所难免的!因此如发现错误还请指出一同学习! 本次题解感谢ljw提供的最后四题题解,本人实在顶不住放弃了! 索引 (难度由题目自身难度与本周 ...

  9. 2017中国大学生程序设计竞赛-哈尔滨站(2/13)

    F.Permutation 题意 给一个n,构造一个1~n的序列使得  pi ≡ 0 ( mod |pi−pi−2| ) for i=3...n 分析 直接暴力让p[i]- p[i-2]=1,先安排奇 ...

最新文章

  1. 8个计算机视觉深度学习中常见的Bug
  2. codeforces 872 D. Something with XOR Queries(思维)
  3. [转]SAP FI/CO 模块设置
  4. 艾瑞发布2018视频云行业报告,网易云信领跑第一阵营
  5. LAMPLNMP自动化安装脚本
  6. 7-4 求下一天 (30 分)
  7. 如何破解 Google Chrome 的隐身模式?
  8. 从EF三层 到 DDD领域驱动设计(1)--------------数据操作
  9. 查询解析MySQL_mysql内部查询过程详解
  10. Go语言实战-golang操作MySQL
  11. php中smarty模板下载,Smarty模板下载|
  12. linux安装中文输入法 -谷歌拼音
  13. 通信笑笑点(2010.08.14)
  14. OpenCASCADE(OCC)读取STEP模型文件到XDE中
  15. 从off-heap到Azul's Zing(JVM)
  16. Celery介绍——手机短信异步发送
  17. OpenCV中拆分通道、合并通道、alpha通道的讲解及实战演示(附python源码 超详细)
  18. HP大中华区总裁孙振耀退休感言(上)
  19. 关于VMware 虚拟机使用时,一打开虚拟机就重启问题-Win11
  20. 力扣765----情侣牵手(C++异或解法)

热门文章

  1. Android滑动浮层(滑动布局中使其中子布局一个浮动)
  2. 在线安装rancher2.4管理K8S集群并部署服务
  3. 奖励来了!四川省中央引导地方科技发展资金认定条件范围及申报奖励补贴
  4. Python-OpenCV 读取和保存视频和解决保存失败的原因分析
  5. BIOS硬盘模式更改为AHCI模式,及更改后win10蓝屏的解决办法
  6. 8乘8led点阵显示数字_8乘以8点阵显示依次从左往右全部点亮,有老哥有51编程语言吗?...
  7. [强化学习实战]马尔可夫决策-悬崖寻路python实现
  8. Vue的计算属性computed和监听属性watch
  9. midl会议_医学图像分析相关的会议
  10. python小乌龟绘制迷宫_用turtle不断的画回字迷宫