[Agc002E]Candy Piles

[Agc002E]Candy Piles

题目大意

\(n\)个数,两人轮流操作,可以做以下操作之一:

  • 删掉一个最大的数
  • 将所有数-1

最后取没的人输,问先手是否必胜?

试题分析

直接决策不知道选哪一个,又没有其它转化操作的思路,索性排一遍序好了。
然后将这个数值作为y轴画出来一个图表,这个东西可以干什么呢?
发现我们的操作就相当于在这个图标的右下角开始走,每次可以向左走或者向上走,没得可走的人就输了。
然后根据这个必胜和必败的关系我们可以推出一个表来,如果一个位置的上方或者右方有一个为0的,那么这个地方就是1,否则就是0。
手推可以发现这个表的一条斜线上的01都是一样的,所以答案就是从右下角画一条斜率为1的直线碰到的那个墙壁的格子。
算一下01就可以了。

#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
 
#define LL long long
 
inline int read(){
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int INF=9999999;
const int MAXN=100010;
 
int N; 
int a[MAXN+1];
 
inline void print(int x){
    if(x==1) puts("First");
    else puts("Second");
}
 
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    N=read();
    for(int i=1;i<=N;i++) a[i]=read();
    sort(a+1,a+N+1); int cnt=1;
    for(int i=N;i>=1;i--){
        if(a[i-1]<=cnt){
            int x1=(a[i]-cnt)&1; if(cnt==a[i-1]) x1^=1;
            if(a[i-1]<cnt){print(x1); return 0;}
            int j=i-1; while(j>1&&a[j-1]==a[j]) --j;
            int x2=(i-1-j)&1,x3;
            if(((x1^1)|(x2^1))==1) x3=1;
            else x3=0; print(x3); return 0;
        } ++cnt;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wxjor/p/9573216.html
今日推荐