1. 程式人生 > >ZOJ - 3964 Yet Another Game of Stones 博弈

ZOJ - 3964 Yet Another Game of Stones 博弈

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 a1, a2, ..., an (1 ≤ ai ≤ 109), indicating the number of stones in each pile.

The third line of each test case contains n integers b1, b2, ..., 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 win

題意:先手Alice 標記為0的堆隨意拿,標記為1的只能拿奇數,標記為2的只能拿偶數個

題解:1.當標記為2時並且該堆為奇數個,必輸;

2.當有標記為2,奇數k個時,先手必須拿去k-1個,否則,後手會操作此堆變為偶數,那麼先手必輸,

3.當有標記為1,個數為1時,無影響;當大於1時,若為奇數,全部拿掉,不然,假設剩兩個,後手既可以一次拿掉,也可以兩次,而先手必須拿兩次,後手可以根據此情況變為必勝狀態;若為偶數,拿掉 總數-1 個,如果不只剩一個,那最少為3個,後手又可以根據自己的情況轉化為必勝

也就是,當標記為2個數為奇數時必敗,標記為2偶數個 和 標記為1 這樣的情況大於1次時 也必敗,其他情況要看每堆的個數了

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int n,a[N],b[N];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		for(int i=1;i<=n;i++)scanf("%d",&b[i]);
		int flag=1,cnt=0,ans=0,p;
		for(int i=1;i<=n;i++)
		{
			if(b[i]==2&&a[i]%2)
			{
				flag=0;
				break;
			}
			if(b[i]==2||(b[i]==1&&a[i]!=1)) cnt++,p=i;
			ans^=a[i];
		}
		if(cnt>=2)
                {
                    flag=0;
                }
                else if(cnt==1)
                {
                    ans=0;
                    for(int i=1;i<=n;i++)
                    {
                        if(p==i)
                        {
                            if(b[i]==1&&a[i]%2==0 || b[i]==2&&a[i]%2) ans^=1;
                        }
                        else ans^=a[i];
                    }
                    if(ans) flag=0;
                }
                else
                {
                    if(!ans) flag=0;
                }
        
		if(flag) cout<<"Alice"<<endl;
		else cout<<"Bob"<<endl;
	}
	return 0;
}