题解 UVA1567 【A simple stone game】
题目大意
一堆石子有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】相关推荐
- 【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 ...
- POJ 3922 A simple stone game(K倍减法游戏)
题目链接:http://poj.org/problem?id=3922 题意:两人取一堆石子,石子有n个. 先手第一次不能全部取完但是至少取一个.之后每人取的个数不能超过另一个人上一次取的数的K倍.拿 ...
- POJ - 3922 A simple stone game(K倍博弈-斐波那契博弈进阶)
题目链接:点击查看 题目大意:给出 n 个石子,两人轮流取石子,取到最后一个石子的人获胜,规定: 第一次取石子不能全部取完 后续取石子的数量必须不超过前一次的K倍 题目分析:大佬博客:https:// ...
- 2017CCPC哈尔滨 H:A Simple Stone Game
题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1008&cid=784 题意: 给你n个正整数,每次可以将某个 ...
- HDU A simple stone game [K倍动态减法游戏]
转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 神牛曹钦翔的论文:从"k ...
- leetcode 877. Stone Game | 877. 石子游戏(递归/动态规划/数学解法)
题目 https://leetcode.com/problems/stone-game/ 题解 搜了一下 stone game,结果.. 进入正题: 一开始写了个递归,超时了.没想出怎么写 dp,看了 ...
- 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 ...
- WHUT第九周训练整理
WHUT第九周训练整理 写在前面的话:我的能力也有限,错误是在所难免的!因此如发现错误还请指出一同学习! 本次题解感谢ljw提供的最后四题题解,本人实在顶不住放弃了! 索引 (难度由题目自身难度与本周 ...
- 2017中国大学生程序设计竞赛-哈尔滨站(2/13)
F.Permutation 题意 给一个n,构造一个1~n的序列使得 pi ≡ 0 ( mod |pi−pi−2| ) for i=3...n 分析 直接暴力让p[i]- p[i-2]=1,先安排奇 ...
最新文章
- 8个计算机视觉深度学习中常见的Bug
- codeforces 872 D. Something with XOR Queries(思维)
- [转]SAP FI/CO 模块设置
- 艾瑞发布2018视频云行业报告,网易云信领跑第一阵营
- LAMPLNMP自动化安装脚本
- 7-4 求下一天 (30 分)
- 如何破解 Google Chrome 的隐身模式?
- 从EF三层 到 DDD领域驱动设计(1)--------------数据操作
- 查询解析MySQL_mysql内部查询过程详解
- Go语言实战-golang操作MySQL
- php中smarty模板下载,Smarty模板下载|
- linux安装中文输入法 -谷歌拼音
- 通信笑笑点(2010.08.14)
- OpenCASCADE(OCC)读取STEP模型文件到XDE中
- 从off-heap到Azul's Zing(JVM)
- Celery介绍——手机短信异步发送
- OpenCV中拆分通道、合并通道、alpha通道的讲解及实战演示(附python源码 超详细)
- HP大中华区总裁孙振耀退休感言(上)
- 关于VMware 虚拟机使用时,一打开虚拟机就重启问题-Win11
- 力扣765----情侣牵手(C++异或解法)
热门文章
- Android滑动浮层(滑动布局中使其中子布局一个浮动)
- 在线安装rancher2.4管理K8S集群并部署服务
- 奖励来了!四川省中央引导地方科技发展资金认定条件范围及申报奖励补贴
- Python-OpenCV 读取和保存视频和解决保存失败的原因分析
- BIOS硬盘模式更改为AHCI模式,及更改后win10蓝屏的解决办法
- 8乘8led点阵显示数字_8乘以8点阵显示依次从左往右全部点亮,有老哥有51编程语言吗?...
- [强化学习实战]马尔可夫决策-悬崖寻路python实现
- Vue的计算属性computed和监听属性watch
- midl会议_医学图像分析相关的会议
- python小乌龟绘制迷宫_用turtle不断的画回字迷宫