题意:n堆棋子,两个人轮流操作,每次可以从每堆中取出一个或取走最大的一堆。求是否先手必胜。

将石子堆从大到小排序,每次操作相当于从(0,0)开始,向上或向右走一步,走到边界即为获胜。
可证除边界每个左下右上对角线上的状态相同。

#include <bits/stdc++.h>
using namespace std;
const int N=110000;
int n;
int a[N];
int cmp(int x,int y){return x>y;}
int main()
{
    //freopen("tt.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n,cmp);
    for(int i=1,j;i<=n;i++)
    {
        if(a[i]==i)
        {
            for(j=i;j<=n&&a[j]==a[i];j++);j--;
            return puts((j-i)&1 ? "First" : "Second"),0;
        }
        if(a[i]>i&&a[i+1]<i)
            return puts((a[i]-i)&1 ? "First" : "Second"),0;
        if(a[i]>i&&a[i+1]==i)
        {
            for(j=i+1;j<=n&&a[j]==a[i+1];j++);j--;
            int t=(j-i-1)&(a[i]-i-1);
            return puts(t&1 ? "Second" : "First"),0;
        }
    }
    return 0;
}

标签: 博弈

添加新评论