AT_agc002_e

考虑条形图,从右下角开始走,每次可以向左走一步(去掉最大数)或者向上走一步(整体减一),走到空的位置的人获胜。
于是就可以 \(O(nV)\) 算状态,但是显然是炸的。
找规律,发现图形中一条斜线上的状态是一样的,考虑证明。
1.先手必败
\((i,j)\) 先手必败,则 \((i+1,j)\)\((i,j+1)\) 先手必胜,则 \((i+1,j+1)\) 先手必败。
所以成斜线。
2.先手必胜
由于已经证明了先手必败,可以只考虑边界上的先手必胜。
考虑相邻位置,若存在先手必败,由于先手必败成一条斜线,所以这一条斜线都可以从那一条斜线转移而来,所以成斜线。
显然横向或纵向的边界上不可能存在连续的先手必胜,而拐角处也不存在连续三个先手必胜,所以边界上所有的先手必胜都与先手必败相邻。
综上,先手必胜也成斜线。
于是就可以直接斜着走,边界上的状态计算显然。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N];
bool dfs(int x,int y){
    if(x>1&&y+1<=a[x-1]){
        return dfs(x-1,y+1);
    }
    if(x<1||y>a[x]){
        return 1;
    }
    if(!dfs(x-1,y)){
        return 1;
    }
    if((a[x]-y)%2==0){
        return 0;
    }
    return 1;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    if(dfs(n,1)){
        puts("First");
    }
    else{
        puts("Second");
    }
    return 0;
}
posted @ 2024-07-27 15:55  ax_by_c  阅读(19)  评论(0)    收藏  举报