目录
一堆的 ,拿的石子某个范围内,在1~K之间
N堆的石子,每次只能从一堆中取
两堆,从一堆中取任意个或从2堆中取相同数量的石子,但不可不取
SG函数
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。
例如N = 3,K = 2。无论A如何拿,B都可以拿到最后1颗石子。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数N,K。中间用空格分隔。(1 <= N,K <= 10^9)
Output
共T行,如果A获胜输出A,如果B获胜输出B。
Input示例
4
3 2
4 2
7 3
8 3
Output示例
B
A
A
B
贴上代码:
#include
#include
#include
using namespace std;
#define ll long long
int main()
{
int n,k,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
if(n%(k+1)==0)
printf("B\n");
else
printf("A\n");
}
return 0;
}
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。
例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。
Input
第1行:一个数N,表示有N堆石子。(1 <= N <= 1000)
第2 - N + 1行:N堆石子的数量。(1 <= A[i] <= 10^9)
Output
如果A获胜输出A,如果B获胜输出B。
Input示例
3
1
1
1
Output示例
A
贴上代码:
#include
#include
#include
using namespace std;
#define ll long long
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int ans=0;
for(int i=0;i
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。
例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数分别是2堆石子的数量,中间用空格分隔。(1 <= N <= 2000000)
Output
共T行,如果A获胜输出A,如果B获胜输出B。
Input示例
3
3 5
3 4
1 9
Output示例
B
A
A
相关问题
Bash游戏
0
Bash游戏 V2
10
Bash游戏 V3
20
Nim游戏
0
Bash游戏 V4
40
威佐夫游戏
0
威佐夫游戏 V2
0
这种题之前学过,不过现在忘得差不多了
我们先来找找规律吧:
假定下面的判断如果为X表示A输,Y表示A赢
第一堆 | 第二堆 | 判断 |
0 | 0 | X |
0 | 1 | Y |
1 | 1 | Y |
1 | 2 | X |
2 | 2 | Y |
2 | 3 | Y |
3 | 3 | Y |
3 | 4 | Y |
3 | 5 | X |
... | ... | ... |
4 | 7 | X |
... | ... | ... |
6 | 10 | X |
... | ... | ... |
我们讨论A输的时候两堆石子的情况,我们从数量小的开始:(0,0)---->(1,2)---->(3,5)---->(4,7)---->(6,10)---->·········
再看看两堆的差值: 0 1 2 3 4
我们发现,每个样例的第一个堆的数量都是前面没有出现的自然数,通过差值逐渐增加的规律得到两堆差值,进而得到另一堆的数量
这些样例也叫奇异局势,就是面对这种情况必输
然后我看了看以前学长讲的ppt,上面有个结论:
以上面的(6,10)为例,即A=6,B=10, 那么等式左边就等于6.472···,向下取整后就等于6,恰好等于A的值,也就是奇异局势
具体得来的其实我也不太清楚,估计还得问问数学家
贴上代码吧:
#include
#include
#include
using namespace std;
#define ll long long
int main()
{
int n;
int a,b;
while(scanf("%d",&n)==1)
{
for(int i=0;ib?b:a;
int B=a>b?a:b;
if((int)((sqrt(5.0)+1)/2*(B-A))==A)
printf("B\n");
else
printf("A\n");
}
}
return 0;
}
最后再加上个SG函数
其实下面讲的为甚sg那样求,然后判断Sg(x)^Sg(y)^Sg(z) == 0时就是奇异局势,我也不理解其中的缘由,先记着吧
•SG函数可以看成各个Nim游戏的和,将问题分成各种Nim问题,从而简化了问题。
•例如:有三堆石头,每次能取的数量为斐波拉系数,即只能取1,2,3,5,8,13,21……这些石头的数量。
首先
定义mex运算:表示最小的不属于这个集合的数。例如:mex{0,1,2,3} = 4、mex{0,1,3,4,5} = 2、mex{} = 0
对于任意的x,Sg(x) = mex{S},S为x的后继状态数值的集合,假设有三个状态Sg(a)、Sg(b)、Sg(c)。那么Sg(x) = mex{Sg(a),Sg(b),Sg(c)}。
设有三堆石头为x、y、z这三堆。那么只要判断Sg(x)^Sg(y)^Sg(z) == 0就行,当成立时就说明面对的是奇异局势,必输,反正必赢。
举例:
附上hdu 1848题目:
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11629 Accepted Submission(s): 5015
Problem Description
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3);
所以,1,2,3,5,8,13……就是菲波那契数列。
在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
1、 这是一个二人游戏;
2、 一共有3堆石子,数量分别是m, n, p个;
3、 两人轮流走;
4、 每走一步可以选择任意一堆石子,然后取走f个;
5、 f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、 最先取光所有石子的人为胜者;
假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。
Input
输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
m=n=p=0则表示输入结束。
Output
如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。
Sample Input
1 1 1 1 4 1 0 0 0
Sample Output
Fibo Nacci
Author
lcy
Source
ACM Short Term Exam_2007/12/13
Recommend
lcy
具体实现请看代码:
#include
#include
#include
#include
#include
using namespace std;
int sg[1001];
int fa[1001];
int mex[1010];
void getsg(int n)
{
for(int i=1;i<=n;i++)
{
memset(mex,0,sizeof(mex));
for(int j=0;fa[j]<=i;j++)
{
mex[sg[i-fa[j]]]=1;
}
for(int k=0;;k++)
{
if(!mex[k])
{
sg[i]=k;
break;
}
}
}
}
int a[120];
int main()
{
int t;
int x,y,z;
int flag;
fa[0]=1;
fa[1]=2;
for(int i=2;i<=1000;i++)
fa[i]=fa[i-1]+fa[i-2];
getsg(1010);
while(scanf("%d%d%d",&x,&y,&z)!=EOF&&(x||y||z))
{
if(sg[x]^sg[y]^sg[z]) printf("Fibo\n");
else printf("Nacci\n");
}
return 0;
}