1. 程式人生 > >P1288 取數遊戲II - 簡單博弈

P1288 取數遊戲II - 簡單博弈

我被博弈的P-position和N-position的定義限制了思想
實際上我可以先尋找必勝態,然後用定義來證明這個必勝態
這是一個環,題目說至少存在一條邊數值為0,先考慮簡單問題,整個環只有一個0,那麼從起點開始,先手不斷取0,“迫使”後手不斷往0靠近,可以證明的是先手決定方向,後手不能違背這個方向走
因為先手可以把一條邊權值置為0,而後手如果跨過這條0邊,到達先手之前在的那個點,如果另一邊權值也為0,後手就輸了,如果不為0,先手也可以將其置為0,然後又回到剛剛那個點,並且此時仍然是後手行動
那麼如果說從起點出發到達的第一個0邊時經過了偶數個點,就是先手必勝(先,後,先,後),最後後手到達了被兩個0邊包圍的局面
接著用定義來證明,當起點到第一個0邊經歷了奇數個點時,先手走一步,後手就面臨必勝局面,所以此時是後手必勝
由於是環,要從兩個方向各走一遍

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 100000 + 10;
const int INF = 1 << 30;
typedef long long ll;
int n,m,a[MAXN];
int main() {
    scanf("%d", &n);
    for(int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
    }
    bool flg = false;
    for(int i=1; i<=n; i++) {
        if(a[i] == 0) {
            if(i % 2 == 0)
                flg = true;
            break;
        }
    }
    for(int i=n; i; i--) {
        if(a[i] == 0) {
            if((n - i + 1) % 2 == 0) 
                flg = true;
            break;
        }
    }
    if(flg) printf("YES");
    else printf("NO");
    return 0;
}