1. 程式人生 > >博弈——混合(尼姆)HDU 4388 Stone Game II

博弈——混合(尼姆)HDU 4388 Stone Game II

1.題目含義:

  一共有n堆石子,每堆石子個數用x表示。現在你可以選擇一堆移除某些石子,但要剩餘k個石子,確保k在[1,n-1]這個區間內。

 移除石子後,還要加入一些石子,加入石子的個數為:k^x,當然你也可以使用技能使得加入的石子個數變為(2k)^x。不過每個人每局遊戲只能使用一次技能。問最後先手是否可以取得勝利,可以的話輸出Yes,否則輸出No。

2.思路:

2.1 先不考慮技能,其實每輪的操作就是將一個大小為x的堆分成大小為k和(x^k)的堆,這裡很關鍵的一點是要能發現分堆之前x中二進位制1的個數與分堆之後k與(x^k)的二進位制1個數和的奇偶性是相同的。這個結論可以這樣想,考慮x的某一位p,就會有四種情況:

2.1.1. 如果x的第p位為1且k的第p位也為1,那麼(x^k)的第p位就是0. ——開始1的個數為2,拆分後1的個數還是2

2.1.2. 如果x的第p位為1且k的第p位也為0,那麼(x^k)的第p位就是1.——開始1的個數為1,拆分後1的個數還是1

2.1.3. 如果x的第p位為0且k的第p位也為1,那麼(x^k)的第p位就是1.——開始1的個數為1,拆分後1的個數還是1

2.1.4. 如果x的第p位為0且k的第p位也為0,那麼(x^k)的第p位就是0.——開始1的個數為1,拆分後1的個數還是0

可以發現無論哪種情況,奇偶性都不會發生變化,這是本題的關鍵。

2.2考慮N堆的情況,總共可操作次數為奇數先手贏,否則先手輸。

2.3考慮技能的情況,技能不會增加1的個數

2.4另外考慮遊戲什麼時候結束,很顯然當一個堆x的二進位制1的個數只有1個的時候,就不能再分了,那麼如果所有的堆都這樣,遊戲就結束了。

2.5  當n+cnt(n堆石子二進位制1的個數)為奇數時,先手取得勝利。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
int t;
int count(int num)
{
	int cnt=0;
	while(num)
	{
		cnt=cnt+num&1;
		num>>=1;
	}
	return cnt;
}
int main()
{
	int j;
	int num;
    cin>>t;
    for(j=1;j<=t;j++)
    {
    	int n;
    	int ans=0;
    	cin>>n;
    	for(int i=0;i<n;i++)
    	{

    		cin>>num;
    		ans=ans+count(num);
		}
		ans=ans+n;
		if(ans&1)
		  cout<<"Case "<<j<<": "<<"Yes"<<endl;
		else
		 cout<<"Case "<<j<<": "<<"No"<<endl;
	}
	return 0;
}