zoukankan      html  css  js  c++  java
  • ZOJ-3964 Yet Another Game of Stones

    Yet Another Game of Stones

    题意: Alice 和 Bob 在进行取石子游戏, 现在一共有n堆石子, 每堆石头有ai个, 然后每堆石头有一个bi属性, 如果bi == 0, Alice取这堆石头就没有限制, 如果bi == 1 那么Alice对这堆石子一次只能取奇数个, 如果bi == 2那么Alice 对这堆石头一次只能取奇数个, 所有石头堆对于Bob来说说取法都没有限制。

    题解:首先我们可以知道 如果存在一个 a = 1, b = 2。 那么Alice无法取这堆, Bob只要将这一堆留到最后, 当其他堆取完的时候下一个是Alice, Alice不能取这堆,所以Bob赢了, 如果下一个取的人是Bob, Bob可以取这一堆, 当Bob取完这一堆的时候,Alice没有东西取所以Bob赢了。

    如果存在一个 a = 偶数, b = 1, 那么Alice最少要分2次奇数去取,如果就剩下这一堆的时候, 轮到Alice, Alice取完之后 Bob还能拿走剩下的,所以Bob赢了,如果轮到Bob, Bob可以直接取完, 所以Bob还是胜利的。 

    如果 a = 偶数, b = 2, Alice就可以直接将这一堆取完, 就不会让Bob形成 a = 1, b = 2的情况, 但是 如果有另外一堆 a = 偶数, b = 2的石头, Alice 可以取完2堆中的一堆, 但是Bob可以使得另外一堆形成 a = 1, b = 2的状态, Bob就必胜了。也就是说如果有2堆 b = 2, Bob必胜, 如果 a = 奇数, b = 2, Bob必胜。

    现在来看 b = 1的情况, 如果b = 1, Alice 不先手将这一堆取完或者 将这一堆变成剩余1的状态, Bob就可以将这一堆变成a = 2, b = 1, 那么Bob 就不会输了。

    所以如果有2堆  b = 1 && a != 1, Alice 可以解决一堆, 但是Bob就可以将另一堆变成 a = 2, b = 1的状态, Bob也会胜利。

    由上面来看, 当b =1 || b = 2的时候, Alice 都要先解决这一堆, 如果有另外一堆 b == 1||b==2,Bob就可以形成将这堆石头变成不会失败的状态。

    当然 如果 只有b = 0的情况, 那么Nimi 博弈 的结论就适用了。 

    所以:当然 有一个 b = 1,  a = 奇, 那么ALice 要先手将这堆取完, 并且对于别的堆来说 先后手就改变了。

    如果有一个 b = 1, a = 偶数, 那么ALice要先手将这堆取成剩下数目为1, 那么将这个1 也放进nimi就, 并且改变先后手的状态就好了。

    如果有一个 b = 2, a = 偶数, 那么ALice 要先手将这堆取完, 并且对于别的堆来说 先后手就改变了。

    如果有一个b = 2, a = 奇数, 那么ALice就已经输了。

    如果出现2堆上述的特殊状态, 那么ALice也输了。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define ULL unsigned LL
     5 #define fi first
     6 #define se second
     7 #define lson l,m,rt<<1
     8 #define rson m+1,r,rt<<1|1
     9 #define max3(a,b,c) max(a,max(b,c))
    10 const int INF = 0x3f3f3f3f;
    11 const LL mod = 1e9+7;
    12 typedef pair<int,int> pll;
    13 const int N = 1e5+5;
    14 int a[N], b[N];
    15 int main(){
    16     int T;
    17     scanf("%d",&T);
    18     while(T--){
    19         int n, t = 0, cnt = 0, flag = 0;
    20         scanf("%d",&n);
    21         for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    22         for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    23         for(int i = 1; i <= n; i++){
    24             if(b[i] == 0){
    25                 t ^= a[i];
    26             }
    27             else if(b[i] == 1 && a[i] == 1) t ^= a[i];
    28             else if(b[i] == 1 && a[i]&1) cnt++;
    29             else if(b[i] == 1 && a[i]%2 == 0) cnt++, t ^= 1;
    30             else if(b[i] == 2 && a[i]&1) flag = 1;
    31             else if(b[i] == 2 && a[i]%2 == 0) cnt++;
    32         }
    33         if(flag || cnt >= 2) cout << "Bob
    ";
    34         else {
    35             if(t != 0){
    36                 if(cnt == 0) cout << "Alice
    ";
    37                 else cout << "Bob
    ";
    38             }
    39             else {
    40                 if(cnt != 0) cout << "Alice
    ";
    41                 else cout << "Bob
    ";
    42             }
    43         }
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    hdu 1392 凸包周长
    hdu 1847
    时间管理101招
    祝大家端午节快乐
    激励员工的二十种非经济手段
    Web2.0个人桌面
    回顾Windows系列的OEM版本历史
    什么是电子商务
    解析3G软件人才成功之道
    成功者应具备的八个心态
  • 原文地址:https://www.cnblogs.com/MingSD/p/8544920.html
Copyright © 2011-2022 走看看