取石子(一)
时间限制:3000 ms | 内存限制:65535 KB
难度:2
描述
一天,TT在寝室闲着无聊,和同寝的人玩起了取石子游戏,而由于条件有限,他/她们是用旺仔小馒头当作石子。游戏的规则是这样的。设有一堆石子,数量为N(1<=N<=1000000),两个人轮番取出其中的若干个,每次最多取M个(1<=M<=1000000),最先把石子取完者胜利。我们知道,TT和他/她的室友都十分的聪明,那么如果是TT先取,他/她会取得游戏的胜利么?
输入
第一行是一个正整数n表示有n组测试数据
输入有不到1000组数据,每组数据一行,有两个数N和M,之间用空格分隔。
输出
对于每组数据,输出一行。如果先取的TT可以赢得游戏,则输出“Win”,否则输出“Lose”(引号不用输出)
样例输入
2
1000 1
1 100
样例输出
Lose
Win
此题来自于一种算法:即石子的总数除与每次拿石子的最大个数加1,若等于零则后方赢否则先拿者赢;
#include<stdio.h>
#include<string.h>
int main()
{
long long int n,m,a,i;
scanf("%lld",&a);
for(i=0;i<a;i++)
{
scanf("%lld%lld",&n,&m);
if(n%(m+1)==0)
{
printf("Lose\n");
}
else
{
printf("Win\n");
}
}
return 0;
}
取石子 (四)
时间限制:1000 ms | 内存限制:65535 KB
难度:4
描述
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
输入
输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。
输出
输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。
样例输入
2 1
8 4
4 7
样例输出
0
1
0
来源
上传者
若两堆物品的初始值为(x,y),且x<y,则另z=y-x;
记w=(int)[((sqrt(5)+1)/2)*z ];
若w=x,则先手必败,否则先手必胜
#include<stdio.h>
#include<string.h>
#include<math.h>
intmain()
{
long long int x,y,a,n,m;
while(scanf("%lld%lld",&x,&y)!=EOF)
{
if(x>y)
{
a=x;
x=y;
y=a;
}
n=y-x;
m=(int)(((sqrt(5)+1)/2)*n);
if(m==x) printf("0\n");
else printf("1\n");
}
return 0;
}
取石子(六)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
最近TopCoder的PIAOYI和HRDV很无聊,于是就想了一个游戏,游戏是这样的:有n堆石子,两个人轮流从其中某一堆中任意取走一定的石子,最后不能取的为输家,注意: 每次只能从一堆取任意个,可以取完这堆,但不能不取。假设PIAOYI先取石子,请你帮他判断他是否能赢(假设他们取的过程中不发生失误,他们足够聪明)。
输入
第一行输入n,代表有n组测试数据(n<=10000)
以下每组测试数据包含两行:第一行:包含一个整数m,代表本组测试数据有m(m<=1000)堆石子;
:第二行:包含m个整数Ai(Ai<=100),分别代表第i堆石子的数量。
输出
若PIAOYI赢输出“PIAOYI”,否则输出“HRDV”注意每组结果占一行。。
样例输入
3
2
1 1
3
3 8 11
2
5 10
样例输出
HRDV
HRDV
PIAOYI
结论就是:把每堆物品数全部异或起来,如果得到的值为0,那么先手必败,否则先手必胜。
异或:例如:1^1=1 0^1=0 0^0=0
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
long long int x,y,a,n,m,j,i;
scanf("%lld",&a);
for(i=0;i<a;i++)
{
n=0;
scanf("%lld",&x);
for(j=0;j<x;j++)
{
scanf("%lld",&y);
n=n^y;
}
if(n==0) printf("HRDV\n");
else printf("PIAOYI\n");
}
return 0;
}
斐波那契博弈:
有一堆物品,两人轮流取物品,先手最少取一个,至多无上限,但不能把物品取完,之后每次取的物品数不能超过上一次取的物品数的二倍且至少为一件,取走最后一件物品的人获胜。
结论是:先手胜当且仅当n不是斐波那契数(n为物品总数)
如HDU2516
#include <iostream>
#include<string.h>
#include<stdio.h>
using namespacestd;
const int N =55;
int f[N];
void Init()
{
f[0] = f[1] = 1;
for(int i=2;i<N;i++)
f[i] = f[i-1] + f[i-2];
}
int main()
{
Init();
int n;
while(cin>>n)
{
if(n == 0) break;
bool flag = 0;
for(int i=0;i<N;i++)
{
if(f[i] == n)
{
flag = 1;
break;
}
}
if(flag) puts("No");
else puts("Yes");
}
return 0;
}