Yet Another Game of Stones---ZOJ Problem 3964

Yet Another Game of Stones

Time Limit: 1 Second      Memory Limit: 65536 KB

Alice and Bob are playing yet another game of stones. The rules of this game are as follow:

  • The game starts with n piles of stones indexed from 1 to n. The i-th pile contains ai stones and a special constraint indicated as bi.
  • The players make their moves alternatively. The allowable moves for the two players are different.
  • An allowable move of Bob is considered as removal of some positive number of stones from a pile.
  • An allowable move of Alice is also considered as removal of some positive number of stones from a pile, but is limited by the constraint bi of that pile.
    • If bi = 0, there are no constraints.
    • If bi = 1, Alice can only remove some odd number of stones from that pile.
    • If bi = 2, Alice can only remove some even number of stones from that pile.
    Please note that there are no constraints on Bob.
  • The player who is unable to make an allowable move loses.

Alice is always the first to make a move. Do you know who will win the game if they both play optimally?

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1 ≤ n ≤ 105), indicating the number of piles.

The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 109), indicating the number of stones in each pile.

The third line of each test case contains n integers b1b2, ..., bn (0 ≤ bi ≤ 2), indicating the special constraint of each pile.

It is guaranteed that the sum of n over all test cases does not exceed 106.

We kindly remind you that this problem contains large I/O file, so it's recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.

Output

For each test case, output "Alice" (without the quotes) if Alice will win the game. Otherwise, output "Bob" (without the quotes).

Sample Input

3
2
4 1
1 0
1
3
2
1
1
2

Sample Output

Alice
Bob
Bob

Hint

For the first test case, Alice can remove 3 stones from the first pile, and then she will win the game.

For the second test case, as Alice can only remove some even number of stones, she is unable to remove all the stones in the first move. So Bob can remove all the remaining stones in his move and win the game.

For the third test case, Alice is unable to remove any number of stones at the beginning of the game, so Bob wins.3

題意:

有n堆石子,Bob每次可以在其中一堆中取走任意數量的石子,但不能不取,而對Alice卻有額外要求,對於某些石子

堆,Alice只能取走偶數個石子(也不能不取),對於某些石子堆,Alice只能取走奇數個石子,現輸入一個數n表示

有n堆石子,接下來n個數分別表示每堆石子的個數,再接下來的n個數表示對Alice的限制,第i個數爲1表示對於第i堆

石子Alice只能取走奇數個,第i個數爲2表示對於第i堆石子Alice只能取走偶數個,第i個數爲0表示沒有限制(Alice和

Bob一樣可以隨便取)現必定Alice先手,不能取者輸,問誰必勝


思路:

這個題目很有意思,剛剛拿到的時候感覺沒什麼頭緒,仔細想了一後會發現,這道題目就是簡單的尼姆遊戲變異版只是需要考慮幾種由於bi造成的Alice

必敗的局面就行了,我把這道題分成了幾種情況(既然有奇偶要求所以思路可以往這上面發散):

1.每堆石子ai與bi只有四種情況    a 奇/偶   b 奇/奇   c 偶/奇    d 偶/偶  (個數/取得方式),沒寫的就是怎麼取都行,即bi=0,那麼就是一個nim遊戲了。

2.對於這四種情況可以知道一旦出現a情況則Alice必輸,因爲對於這一堆最後的一塊一定是Bob取走,就算當前對於Bob是必輸態(不看這一堆),他只要取了這一堆的最後一粒,那麼必輸態就轉換給力Alice,而Alice一點辦法也沒有。

3.而其他三種狀態如d,Alice需要一次性把這堆取完,不然Bob只需要在這一堆去取走一個石子,那麼b情況就變成了a情況。對於c和b,應當知道Alice應該一次全部取完或者剩下一個,因爲Bob會利用bi的限制,使Alice不能一次性取完這一堆,在上面浪費步驟。而對於這三種情況,可以看出來,雖然Alice是先手,但是也只能改變一次,如果這三種狀態存在1種以上,那麼Alice就一定會輸,因爲Bob不會放過這個機會,即兩人第一是最聰明的這一前提。

4.如果沒有a狀態並且b,c,d中只有一種,那麼Alice需要把b,c,d狀態中存在的全部取完或者只剩一個,然後剩下的石子,在判斷就是一個簡單的nim問題了,但是變爲Bob爲先手。

5.如果a,b,c,d四種狀態都沒有即對Alice沒有限制,那麼就是直接對堆異或,就是一個Alice先手的nim遊戲。

下面代碼:

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int a[100100],b[100100];
int main()
{
    int t,n;
    int flag1,flag2,flag3;
    scanf("%d",&t);
    while(t--)
    {
         int sum=0;
        flag1=flag2=flag3=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&b[i]);

        for(int i=0;i<n;i++)
        {
            if((a[i]%2)&&(b[i]==2)) flag1=1;///奇偶
            if((!(a[i]%2)&&(b[i]==2)||!(a[i]%2)&&(b[i]==1)||(a[i]%2)&&(b[i]==1))&&(a[i]>1)) flag2++;
               ///偶偶                ///偶奇                  ///奇奇
        }

        if(flag1||flag2>1)
        {
            printf("Bob\n");
            continue;
        }
        else if(flag1==0&&flag2==0)///四態都沒有
        {
            sum=0;
            for(int i=0;i<n;i++)
            sum^=a[i];
            if(sum!=0) printf("Alice\n");
            else printf("Bob\n");
            continue;
        }

        for(int i=0;i<n;i++)
        {
            if(!(a[i]%2)&&(b[i]==2))  a[i]=0;
            if(!(a[i]%2)&&(b[i]==1))  a[i]=1;
            if((a[i]%2)&&(b[i]==1)&&(a[i]>1))  a[i]=0;
        }

        for(int i=0;i<n;i++)
           // if()
            sum^=a[i];
        if(sum==0) printf("Alice\n");
        else printf("Bob\n");

    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章