Game HDU - 3389 (博弈论)

Bob and Alice are playing a new game. There are n boxes which have been numbered from 1 to n. Each box is either empty or contains several cards. Bob and Alice move the cards in turn. In each turn the corresponding player should choose a non-empty box A and choose another box B that B<A && (A+B)%2=1 && (A+B)%3=0. Then, take an arbitrary number (but not zero) of cards from box A to box B. The last one who can do a legal move wins. Alice is the first player. Please predict who will win the game.

InputThe first line contains an integer T (T<=100) indicating the number of test cases. The first line of each test case contains an integer n (1<=n<=10000). The second line has n integers which will not be bigger than 100. The i-th integer indicates the number of cards in the i-th box.OutputFor each test case, print the case number and the winner's name in a single line. Follow the format of the sample output.Sample Input

2
2
1 2
7
1 3 3 2 2 1 2

Sample Output

Case 1: Alice
Case 2: Bob


题意:
编号可以满足B<A && (A+B)%2=1 && (A+B)%3=0就可以把石子从A移动到B。

思路:
阶梯博弈

问题导入我就不BB了,普通阶梯博弈的结论就是奇数阶的异或和。
1.1 如果先手必败,挪动偶数阶的石子,对方肯定将挪动的石子再次挪到偶数阶上,保持你的必败状态。
1.2 如果先手必败,挪动奇数阶的石子,相当于取走nim博弈中的石子,你的必败态并未改变。
2.1 如果先手必胜,挪动偶数阶的石子。。。。。你没有必要这么做。。
2.2 如果先手必胜,挪动奇数阶的石子,就把问题1.1,1.2丢给了对方。

这个题画个图,变形一下就行了。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);
int n;
int num[maxn];
int main()
{
//    ios::sync_with_stdio(false);
//    freopen("in.txt","r",stdin);

    int T;
    int cases=0;
    scanf("%d",&T);
    while(T--){
        cases++;
        scanf("%d",&n);
        int ans=0,x;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            if(i%6==0||i%6==2||i%6==5){
                ans^=x;
            }
        }
    printf("Case %d: ",cases);
        if(ans){printf("Alice\n");}
        else printf("Bob\n");
    }

    return 0;
}
View Code

 

posted @ 2019-03-13 12:10  断腿三郎  阅读(296)  评论(0编辑  收藏  举报