lightoj1296----博弈

这道题跟刘汝佳书上的例题一模一样

先给出题目的意思:有n堆石子,分别有a1,a2,......an个,两个游戏者轮流操作,每次可以选一堆,拿走至少一个石子,但不能超过一半的石子。谁不能取,就算输

给出数据范围(T<=100)。每组数据的第一行为整数n(1<=n<=100),第二行包括a1,a2,......,an(1<=ai<=2*1e18)

首先一个不用想都知道的东西,大家先求出单个游戏的值,然后在异或起来,这样便可以求值

但是这个跟nim博弈不同点就在于这个东西的取法是不能超过一半的石子,这就有点蛋疼了,但是数据范围又有点大,有不好找到明显的一方能明明白白安排对方的结论,这时便考虑打表找规律,事实上刘汝佳的书也是找的规律

(这个规律也同时教了我一点,有时候规律也可以分成奇偶分,但是要在题目上面合理假设)

下面是代码:

    

 1 #include<cstring>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<iostream>
 5 using namespace std;
 6 int t,n,a;
 7 
 8 int sg(int b){
 9     if(b%2==0)    return b/2;
10     else return sg(b/2);
11 } 
12 
13 int main(){
14     scanf("%d",&t);
15     for(int kase=1;kase<=t;kase++){
16         scanf("%d",&n);
17         int ans=0;
18         while(n--){
19             scanf("%d",&a);
20             ans^=sg(a);
21         }
22         printf("Case %d: ",kase);
23         if(ans==0) printf("Bob\n");
24         else printf("Alice\n");
25     }
26     return 0;
27 }
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/9906748.html