Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 592 Accepted Submission(s): 341

Problem Description

After he has learned how to play Nim game, Mike begins to try another stone game which seems much easier.

The game goes like this: Two players start the game with a pile of n stones. They take stones from the pile in turn and every time they take at least one stone. The one who goes first can take at most n-1 stones for his first move. From then on a player can take at most k times as many stones as his opponent has taken last time. For example, if one player take m stones in his turn, then the other player can take at most k × m stones next time. The player who takes the last stone wins the game. Suppose that those two players always take the best moves and never make mistakes, your job is to find out who will definitely win the game.

Input

The first line contains a integer t, indicating that there are t test cases following.(t<=20).

Each test case is a line consisting of two integer n and k.(2<=n<=10^8,1<=k<=10^5).

Output

For each test case, output one line starting with “Case N: ”, N is the case number. And then, if the first player can ensure a winning, print the minimum number of stones he should take in his first turn. Otherwise, print “lose”. Please note that there is a blank following the colon.

Sample Input

5

16 1

11 1

32 2

34 2

19 3

Sample Output

Case 1: lose

Case 2: 1

Case 3: 3

Case 4: lose

Case 5: 4

【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=2486

【题解】

/*
首先分类讨论一下;
①k=1
则除了2^i之外,都是先手赢;
先手可以进行如下的策略;
把剩余的石子的数目转换成二进制;
先手每次可以把二进制表示的最后一个1给删掉;
比如6的二进制110
则减去2
->100
这时对方是没办法减去这一个1的,因为对方不能取的比你大(k=1)
所以对方只能取1或2
如果取1的话
->011
你还是按照一样的策略每次取最后一个1;
对方还是不能取倒数第二个1;
....
"所以你总是能取最后一个1。"
也即你能赢.
取2同理
总之你只要每次都取最后一个1表示的数,则你总是可以赢;
当然如果是2^i,则你不能取走仅有的一个1;
只能减去1..2^i-1中的任意一个数字;
如果你取到只剩下2^(i-1)以下,则对方直接赢了(对方最多可以取2^(i-1)个);
但是如果你取到剩下2^(i-1)以上;
那二进制形式里面必然还剩下2个以上的1;
则对方可以用上述策略击败你;(每次取最后一个1);
②k=2
则除非n为斐波那契数列的某一项,否则先手一定赢;
(1,2,3,5,8,13...)
有性质:任意一个整数x总能分解成若干项不相邻的斐波那契数列的和;
(这里的整数x是不属于斐波那契数列中的任意一项的整数);
且有f[i+2]>2*f[i];
那么如果一个整数不是斐波那契数列
比如12=1+3+8
则可以把它类比成二进制的形式111
我们还是每次取走最后一个1;
这里的1代表的是1;
就变成110
但是对方是没办法取走倒数第二个1的
因为f[i+2]>2*f[i];(任意一个整数可以由不相邻的斐波那契数相加构成)
这就说明在对方可取的范围里面不足以减去第二个1;
对方只能把倒数第二个1拆掉;
这样可以保证总是你取走最后一个1;
所以你总是能够赢.
相应的如果你面临了斐波那契数列
则你必须把那唯一的一个1拆掉(类似二进制);
则对方可以任意地拆掉你留给它的最后的一个1;
然后让你面临尴尬的局面。balabala
③k>2
我们考虑构造像k=2的那总数列a;
设我们已经构造到数列a第的i项a[i]了,且1..b[i](内除了这个数列的元素)
都能由若干个数列ai的元素构成且它们相邻之间a[xn]/a[xn-1]>k
那么有a[i+1]=b[i]+1;
因为b[i]+1这个元素没办法由1..a[i]构造成;
所以只能新加这么一项了;
然后要求b[i+1]了;
显然b[i]+1..b[i+1]内这些数的构成都要a[i+1]参与;
现在的问题是要给a[i+1]寻找"合作的伙伴";
显然那些合作伙伴的下标t;
要满足k<a[i+1]/a[t];
可以维护这么一个t值(因为a[i]是单调递增的,所以很好维护的);
则b[i+1]=a[i+1]+b[t];
(1..b[t]都是能用不超过a[t]的项构成的(它们之间的倍数关系大于k))
如果不存在t的话b[i+1]=a[i+1]=b[i]+1;
最后看看n在不在a数列中,不在的话先手赢,否则先后输;
具体原因上面已经讨论过了(都是类比二进制);
(k=1、2的情况都能归结到这种情况);
是先手赢的话一直减a数列中的数(从大到小能减就减);
最小的那个数字肯定就是我们上面一直讨论的"数字1"了;
你把它输出就好;
最坏情况是n=1e8,k=1e5
看看数列的长度是多少就可以了;(作为数列的size);
*/

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int MAXN = 1000000;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); int T;
LL n,k;
LL a[MAXN],b[MAXN]; int main()
{
//freopen("F:\\rush.txt","r",stdin);
int ii = 0;
for (rei(T);T--;)
{
ii++;
rel(n);rel(k);
a[1] = b[1] = 1;
LL i = 1,t = 0;
while (a[i]<n)
{
i++;
a[i] = b[i-1]+1;
while (a[t+1]*k < a[i]) t++;
if (a[t]*k<a[i])
b[i] = a[i] + b[t];
else
b[i] = a[i];
}
printf("Case %d: ",ii);
if (a[i]==n)
puts("lose");
else
{
int ans = -1;
rep2(j,i-1,1)
if (n>=a[j])
{
n-=a[j];
ans = a[j];
}
printf("%d\n",ans);
}
}
return 0;
}

【hdu 2486】A simple stone game的更多相关文章

  1. 【hdu 5996】dingyeye loves stone

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s) ...

  2. 【HDU 5399】Too Simple

    题 Description Rhason Cheung had a simple problem, and asked Teacher Mai for help. But Teacher Mai th ...

  3. 【HDU 1757】 A Simple Math Problem

    题 Description Lele now is thinking about a simple function f(x). If x < 10 f(x) = x. If x >= 1 ...

  4. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  5. 一本通1548【例 2】A Simple Problem with Integers

    1548:[例 2]A Simple Problem with Integers 题目描述 这是一道模板题. 给定数列 a[1],a[2],…,a[n],你需要依次进行 q 个操作,操作有两类: 1 ...

  6. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  7. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  8. 【HDOJ 5399】Too Simple

    pid=5399">[HDOJ 5399]Too Simple 函数映射问题 给出m函数 里面有0~m个函数未知(-1) 问要求最后1~n分别相应仍映射1~n 有几种函数写法(已给定的 ...

  9. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

随机推荐

  1. enq: TX - row lock contention故障处理一则

    一个非常easy的问题,之所以让我对这个问题进行总结.一是由于没我想象的简单,在处理的过程中遇到了一些磕磕碰碰,甚至绕了一些弯路.二是引发了我对故障处理时的一些思考. 6月19日,下午5点左右.数据库 ...

  2. Android判断App是否在前台运行

    版权声明:本文为博主原创文章,未经博主允许不得转载. //当前应用是否处于前台 private boolean isForeground(Context context) { if (context ...

  3. 用jquery获取单选按钮选中的内容 和 获取select下拉列表选中的值

    1.<label><input name='reason' type='radio' value='您的评论内容涉嫌谣言' />您的评论内容涉嫌谣言</label> ...

  4. vue项目在其他电脑运行报错

    解决方法1.先删除node_modules文件夹2.$ cnpm cache clean 命令清除掉cache缓存3.cnpm install4.npm run dev

  5. 【Codeforces Round #442 (Div. 2) C】Slava and tanks

    [链接] 我是链接,点我呀:) [题意] 有n个位置,每个位置都可能有不定数量的tank; 你每次可以选择一个位置投掷炸弹. 并且,这个位置上的所有tank都会受到你的攻击. 并且失去一点体力. 然后 ...

  6. AUC(Area Under roc Curve )计算及其与ROC的关系

    转载: http://blog.csdn.net/chjjunking/article/details/5933105 让我们从头说起,首先AUC是一种用来度量分类模型好坏的一个标准.这样的标准其实有 ...

  7. NSString常见用法

    1.创建常量字符串 NSString *str = @"Hello World!"; 2.创建空字符串,给予赋值 NSString *str = [[NSString alloc] ...

  8. [WPF自定义控件库]排序、筛选以及高亮

    1. 如何让列表的内容更容易查找 假设有这么一个列表(数据源在本地),由于内容太多,要查找到其中某个想要的数据会比较困难.要优化这个列表,无非就是排序.筛选和高亮. 改造过的结果如上. 2. 排序 在 ...

  9. 33、给华美A100刷固件

    给HAME A100刷固件 目的: 1. 给HAME A100刷固件 2. 配置上UVC驱动 3. 修改内核自带的UVC驱动,使其支持我们自制的二合一摄像头 4. 移植mjpg-streamer 5. ...

  10. crontab经验 分类: B3_LINUX 2015-03-06 11:17 282人阅读 评论(0) 收藏

    1.基本格式  第1列分钟1-59  第2列小时1-23(0表示子夜)  第3列日1-31  第4列月1-12  第5列星期0-6(0表示星期天)  第6列要运行的命令 2.关于日志 (1)基本日志位 ...