Gym 100827G Number Game (博弈)

Number Gamec++

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?ide

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.spa

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

Sample Inputcode

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

Sample Outputrem

Bob
Alice
Bob
Aliceit

題意:輸入一個N, 而後給一個1~N的數列。兩我的輪流拿數字,當一個數字兩邊沒有比它大的數字的時候(旁邊是空格也能夠),這個數字就能夠被拿走。io

題解:class

考慮到若是要拿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;
}
相關文章
相關標籤/搜索