有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1066
必胜策略:令 n = (k + 1) * r + s ; A第一次取s个,让B面对k+1倍数的局面,如果B取m个则A取k+1 - m个。
#include
#include
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while( t-- )
{
int n, k;
scanf("%d%d", &n, &k);
if( n <= k )
printf("A\n");
else
{
int tmp = n % (k + 1);
if( tmp == 0 )
printf("B\n");
else
printf("A\n");
}
}
return 0;
}
有一堆石子共有N个。A B两个人轮流拿,A先拿。每次只能拿1,3,4颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1067
分析:连续找一些书测试,可以发现当 n % 7 == 0 || == 2 时B胜,其余情况A胜
#include
using namespace std;
int main()
{
int t, n;
scanf("%d", &t);
while( t-- )
{
scanf("%d", &n);
int tmp = n % 7;
if( tmp == 0 || tmp == 2 )
printf("B\n");
else
printf("A\n");
}
return 0;
}
有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。
例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1069
分析:尼姆博弈,对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算.
#include
using namespace std;
int main()
{
int n;
while( ~scanf("%d", &n) )
{
int ans = 0;
int num;
for( int i=0; i
有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。
例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1072
分析:威佐夫博弈
两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜. 局势(N,M)(N N==(int)((1.0+sqrt(5.0))/2.0*(M-N))时,该局势为奇异局势,后拿者必胜. #include