Gym 100827G Number Game (博弈)

Number Game

Alice and Bob are playing a game on a line of N squares. The line is initially populated with one of each of the numbers from 1 to N. Alice and Bob take turns removing a single number from the line, subject to the restriction that a number may only be removed if it is not bordered by a higher number on either side. When the number is removed, the square that contained it is now empty. The winner is the player who removes the 1 from the line. Given an initial configuration, who will win, assuming Alice goes first and both of them play optimally?

Input
Input begins with a line with a single integer T, 1 ≤ T ≤ 100, denoting the number of test cases. Each test case begins with a line with a single integer N, 1 ≤ N ≤ 100, denoting the size of the line. Next is a line with the numbers from 1 to N, space separated, giving the numbers in line
order from left to right.

Output
For each test case, print the name of the winning player on a single line.

Sample Input

4 4
2 1 3 4
4
1 3 2 4
3
1 3 2
6
2 5 1 6 4 3

Sample Output

Bob
Alice
Bob
Alice

题意:输入一个N, 然后给一个1~N的数列。两个人轮流拿数字,当一个数字两边没有比它大的数字的时候(旁边是空格也可以),这个数字就可以被拿走。

题解:

考虑到如果要拿1,就要先把1旁边的两个数都拿走,那么如果1旁边两个数其中的一个已经被拿走,两个人肯定是不想拿剩下的一个数,所以此时所走的步数已经确定。Alice作为先手,优势就是选择两数之一。1在旁边特殊考虑一下,其实原理是一样的。

画个图表示下(略抽象):

附上几组数据:

8
7 3 5 2 4 1 6 8
6
1 5 3 4 2 6
7
7 2 4 6 3 1 5
6
1 5 3 4 2 6
5
3 4 1 5 2

Bob
Alice
Alice
Alice
Bob

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005;
int a[N];

// 窝乃辣鸡
// 感谢小杭=.=

bool MDZZ()
{
    int n;
    scanf("%d", &n);
    int pone, pl, pr;
    pl = 0; pr = n+1;
    for (int i = 1; i <= n; ++i) {
        scanf("%d", a+i);
        if (a[i] == 1) pone = i;
    }
    for (int i = pone - 1; i > 1; --i) {
        if (a[i] < a[i-1]) { pl = i-1; break; }
    }
    for (int i = pone + 1; i < n; ++i) {
        if (a[i] < a[i+1]) { pr = i+1; break; }
    }
    int ex = (n - pr + 1) + (pl);

    int ls = pone - pl - 1; // 左边中间的
    int rs = pr - pone - 1; // 右边中间的

    if (n == 1) return true;

    // 如果1在最左边或者最右边
    if (pone == 1 || pone == n) {
        if ((ex+1) % 2 == 0) return true;
    }
    // 1不在边上
    else{
        bool f = false;
        // 能先拿1左边的数
        if ((pl == 0) || (ls > 1)) {
            if ((ex+ls+1) % 2 == 0) return true;
            f = true;
        }
        // 能先拿1右边的数
        if ((pr == n+1) || (rs > 1)) {
            if ((ex+rs+1) % 2 == 0) return true;
            f = true;
        }
        // 1左右的数都不能拿 必须把全部的拿走才行
        if (!f && n % 2 == 1) return true;
    }
    return false;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--) puts(MDZZ() ? "Alice" : "Bob");
    return 0;
}
时间: 2024-08-07 00:13:30

Gym 100827G Number Game (博弈)的相关文章

UVA 1558 - Number Game(博弈dp)

UVA 1558 - Number Game 题目链接 题意:20之内的数字,每次可以选一个数字,然后它的倍数,还有其他已选数的倍数组合的数都不能再选,谁先不能选数谁就输了,问赢的方法 思路:利用dp记忆化去求解,要输出方案就枚举第一步即可,状态转移过程中,选中一个数字,相应的变化写成一个函数,然后就是普通的博弈问题了,必胜态之后必有必败态,必败态之后全是必胜态 代码: #include <stdio.h> #include <string.h> const int N = 105

2016-2017 ACM-ICPC CHINA-Final

A Gym 101194A Number Theory Problem B Gym 101194B Hemi Palindrome C Gym 101194C Mr. Panda and Strips D Gym 101194D Ice Cream Tower E Gym 101194E Bet F Gym 101194F Mr. Panda and Fantastic Beasts G Gym 101194G Pandaria H Gym 101194H Great Cells I Gym 1

Gym - 101246D 博弈

题意:一个无向有环的图,从 1 号结点起火,开始蔓延,两个绝顶聪明的人轮流走,谁不能走谁输,输出输的人: 分析: 当时知道是博弈,但是想当然的以为 1 号结点有一个奇数层,就必胜:其实不是这样的,当一个人往奇数层走的时候,来到分叉点,另一个会找一个偶数走. 于是,还是得用SG博弈, 1.将图转换为一个有向无环图: 2.SG函数,下一个状态是子节点: #include <bits/stdc++.h> using namespace std; int n,m; const int maxn = 1

Gym - 100952G (博弈)

Statements Alice and Bob play the following game. They choose a number N to play with. The rules are as follows: - They write each number from 1 to N on a paper and put all these papers in a jar. - Alice plays first, and the two players alternate. -

数位DP || Gym 101653R Ramp Number

每一位都大于等于前一位的数叫Ramp Number 给一个数,如果不是Ramp Number输出-1,如果是Ramp Number输出比它小的Ramp Number的个数 只和每一位上的数字有关 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <queue> #include &l

Gym - 100548H The Problem to Make You Happy 2014-2015 ACM-ICPC, Asia Xian Regional Contest (BFS+博弈)

题意:Bob和Alice在一张有向无环图上移动,给定二者的起点,Bob先手.Bob的失败条件是不能移动或者与Alice相遇.两个人都采取最优策略,求Bob是否会赢 分析:银牌题.先确定所有的失败状态,然后根据这些反向状态BFS. 用\(dp[i][j][0or1]\)表示bob在i点,Alice在j点,当前移动的人是bob还是Alice的情况, bob是否必败. 首先能确定的是 \(dp[i][j][0] = dp[i][j][1] = 0\), 对于出度为0的点\(i\),\(dp[i][j]

gym/102059/problem/I. Game on Plane SG函数做博弈

传送门: 题意: 给定一个正n边形的点.双方轮流连点成线,要求所画的线不能与之前的线相交.当某个人连成一个回路,这个人就输了.问先手必胜还是后手必胜. 思路: SG函数,因为一条线相当于把图劈成了两半,所以每次用异或运算推过来. /* * @Author: chenkexing * @Date: 2019-01-13 16:17:46 * @Last Modified by: chenkexing * @Last Modified time: 2019-01-15 18:33:24 */ #in

CodeForces Gym 100935D Enormous Carpet 快速幂取模

Enormous Carpet Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 100935D Description standard input/outputStatements Ameer is an upcoming and pretty talented problem solver who loves to solve problems using computers.

HDU 3980 Paint Chain(博弈 SG)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3980 Problem Description Aekdycoin and abcdxyzk are playing a game. They get a circle chain with some beads. Initially none of the beads is painted. They take turns to paint the chain. In Each turn one p