Triple Nim
Time Limit: 2000MS Memory limit: 65536K
题目描述
Alice and Bob are always playing all kinds of Nim games and Alice always goes first. Here is the rule of Nim game:
There are some distinct heaps of stones. On each turn, two players should remove at least one stone from just one heap. Two player will remove stone one after another. The player who remove the last stone of the last heap will win.
Alice always wins and Bob is very unhappy. So he decides to make a game which Alice will never win. He begins a game called “Triple Nim”, which is the Nim game with three heaps of stones. He’s good at Nim game but bad as math. With exactly N stones, how many ways can he finish his target? Both Alice and Bob will play optimally.
输入
输出
示例输入
3
3
6
14
示例输出
0
1
4
提示
来源
题目链接http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/3566.html
题意很好理解,就是有一堆石子,一共有n个,把n个石子分成三堆,求有多少种分配的方式能够使得bob win?
很容易就能够明白题目是让干什么的,这道题目就是一道尼姆博弈的题目,先来讲下尼姆博弈,其实很简单,有n堆石子,如果n堆石子的异或和是0,则先手必败,否则先手胜。尼姆博弈是利用二进制的思想,那么本题也可以利用二进制的思想,可知,如果要使得Alice输并且Alice为先手,只需要使得三堆石子异或等于0 即可,首先共有n个石子,把n转化成二进制来表示,假设其中有k个1存在,如果要使得三堆石子异或为0,则在三堆石子数的二进制数的每位上1的个数都要是偶数位,又可知,在二进制中,高位的1是由低位进位而得到的,也就是说高位的1可以分解成两个低位的1,当n是奇数的时候,最低位为1且没有办法分解,所以输出0,所以当n为偶数的时候,就有(3^k - 3)/6个,减去3是去掉一个为0的情况,除6是应为本题求得是排列。。。
#include <stdio.h>
#include <math.h>
int Binary(int num){
int cnt = 0;
while(num){
if(num % 2)
cnt ++;
num /= 2;
}
return cnt;
}
int main(){
int t;
scanf("%d",&t);
while(t --){
int num;
scanf("%d",&num);
if(num % 2){
printf("0\n");
continue;
}
int ans = Binary(num);
long long cnt = (pow(3,ans) - 3) / 6;
printf("%lld\n",cnt);
}
return 0;
}