HDU 6105 Gameia

Problem Description

Alice and Bob are playing a game called ‘Gameia ? Gameia !’. The game goes like this :
0. There is a tree with all node unpainted initial.
1. Because Bob is the VIP player, so Bob has K chances to make a small change on the tree any time during the game if he wants, whether before or after Alice’s action. These chances can be used together or separate, changes will happen in a flash. each change is defined as cut an edge on the tree.
2. Then the game starts, Alice and Bob take turns to paint an unpainted node, Alice go first, and then Bob.
3. In Alice’s move, she can paint an unpainted node into white color.
4. In Bob’s move, he can paint an unpainted node into black color, and what’s more, all the other nodes which connects with the node directly will be painted or repainted into black color too, even if they are white color before.
5. When anybody can’t make a move, the game stop, with all nodes painted of course. If they can find a node with white color, Alice win the game, otherwise Bob.
Given the tree initial, who will win the game if both players play optimally?

Input

The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with two integers N and K : the size of the tree and the max small changes that Bob can make.
The next line gives the information of the tree, nodes are marked from 1 to N, node 1 is the root, so the line contains N-1 numbers, the i-th of them give the farther node of the node i+1.

Limits
T≤100
1≤N≤500
0≤K≤500
1≤Pi≤i

Output

For each test case output one line denotes the answer.
If Alice can win, output “Alice” , otherwise “Bob”.

Sample Input

2
2 1
1
3 1
1 2

Sample Output

Bob
Alice

Source

2017 Multi-University Training Contest - Team 6

Recommend

liuyiding | We have carefully selected several similar problems for you: 6119 6118 6117 6116 6115

这个题花了我半天时间才想明白,在这里我一定要讲得清清楚楚。
题意:
0.给出一个有n个节点的二叉树,二叉树的所有节点都是没有被进行过标记的(没有被染色)。
1.Alice只能将一个未被染色的节点染成白色。但是游戏开始时,Alice先手。
2.Bob是人民币玩家,Bob能将一个未被染色的节点染成黑色,并且感染和这个节点相邻的节点,也使其变成黑色(无论周围的节点是否已经被处理,都被重新染成黑色);另外,Bob还有K次开挂的机会,可以在任意时候使用,就是剪掉一条边,让一棵树变成两棵树…(最后可以变成好多好多颗树= =)
3.当所有的节点都被染过色的时候,若有白色节点则Alice赢,全为黑色则Bob赢,游戏结束。

分析:
1.Alice的角度:我必须每次都染父亲节点 ,这样一来Bob就被我牵着鼻子走。如果有某个节点有两个及其以上孩子节点,Alice必胜(此时Alice的一步操作需要Bob两次弥补,它弥补不过来了,哈哈)。我需要奇数个元素的子树。
2.Bob的角度:我的剪刀可以减掉一条边,但是如果剪下来剩下了单独的点是毫无意义的(要么这个点已经被染过色了,要么这个点会被Alice染成白色就必输了,浪费)。我需要将整个树分成 只有两个节点的 一堆树 。所以,树必须是偶数个节点,K>=n/2-1。如果剪不完,那么在Alice眼里就会存在有奇数子树(把树转90度看= =),就GG了。

总结一下Bob的获胜条件:
1.n为偶数&&被剪后所有子树也都是偶数个节点 直到变成一对一对儿的小树
2.K>=n/2-1;

PS:Bob的剪刀一开始全部用光,不然有可能把自己本可以走的步骤给涂死了= =
这样想比较简单。
其余都是Alice获胜!

AC代码:

#include<iostream>
#include<cstring>
using namespace std;
int n, k;
int T; int temp;
int a[10000];
int sz[10000];
int main()
{
    cin >> T;
    bool flag = 0;
    while (T--)
    {
        cin >> n >> k;
        flag = 0;
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i++)
        {
            sz[i] = 1;
        }
        for (int i = 2; i <= n; i++)
        {
            cin >> a[i];
        }
        for (int i = n; i >= 1; i--)
        {
            if (sz[i] >= 3)
            {
                flag = 1;
            }
            sz[a[i]] += (sz[i]%2);//子树4不4偶数树
            /*if (sz[i] != 2)
            {
                sz[a[i]] += 1;
            }*/
        }
        if (flag == 0 && n % 2 == 0 && k >= (n / 2 - 1))
            cout << "Bob" << endl;
        else
            cout << "Alice" << endl;
    }
    //system("pause");
    return 0;
}

标程:

#include <iostream>
using namespace std;
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N = 1e5 + 10;
int T, n, K, par[N], sz[N];
int main() 
{
    scanf("%d", &T);
    rep(i, 0, T) 
    {
        scanf("%d%d", &n, &K);
        rep(i, 2, n + 1) 
            scanf("%d", par + i);
        rep(i, 1, n + 1) 
            sz[i] = 1;
        bool ok = 1;
        per(i, 1, n + 1) 
            ok &= sz[i] <= 2, sz[par[i]] += sz[i] & 1;
        puts(n % 2 == 0 && K >= n / 2 - 1 && ok ? "Bob" : "Alice");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值