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. 基于cropper.js的图片上传和裁剪

    项目中要求图片上传并裁剪的功能,之前也有接触过很多图片裁剪插件,效果体验不是很好,今天推荐一款好用的插件-cropper,超级好用,裁剪功能丰富,满足了各种需求. 功能: 1:点击选择图片,弹出文件夹 ...

  2. spring mvc笔记

    80214shuenjian224shuenjian@sina 北风网公开课课程大纲1.学习MVC框架的步骤2.Spring MVC运行机制3.演示Spring MVCAdd Maven suppor ...

  3. BC 52 div2 A Victor and Machine

    简单数学题,把这道题目贴上去的不过为了不想看到这个月写了某个数字篇博客,该数字有点不吉利... 近期没有学习的欲望.. . 集中不了注意力,今天打BC还是做出来一题,尽管涨分了,真心希望能接近cf的水 ...

  4. amazeui学习笔记--css(常用组件1)--小徽章Badge

    amazeui学习笔记--css(常用组件1)--小徽章Badge 一.总结 1.am-badge:添加am-badge来声明小徽章对象 <span class="am-badge a ...

  5. 关于YUM错误,Error: rpmdb open failed

    错误如题: rpmdb: Thread/process / failed: Thread died in Berkeley DB library error: db3 error(-) from db ...

  6. Android RxJava基本流程和lift源码分析

    基本结构 我们先来看一段最基本的代码,分析这段代码在RxJava中是如何实现的. Observable.OnSubscribe<String> onSubscriber1 = new Ob ...

  7. HDU 2063 过山车 第一道最大二分匹配

    http://acm.hdu.edu.cn/showproblem.php?pid=2063 题目大意: m个女生和n个男生一起做过山车,每一排必须一男一女,而每个女孩愿意和一些男生坐一起,, 你要找 ...

  8. 16进制串与ASCII字符串相互转换

    提供两个函数,方便十六进制串与ASCII 字符串之间的相互转换,使用函数需要注意的是返回的串是在堆上通过 calloc 分配的,所以,记得使用完返回值释放该块,并且将指向该块的指针 =NULL .// ...

  9. hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    ...

  10. iOS数据存储简要笔记

    1.  数据存储常用的方式 (1)XML 属性列表(plist)归档 (2)preference(偏好设置) (3)NSKeyedArchiver归档(NSCoding) (4)  SQLite3   ...