【AGC002E】Candy Piles 博弈论

来源:互联网 发布:淘宝手办现货可信? 编辑:程序博客网 时间:2024/06/05 00:49

题目大意

  有n堆糖果,第i堆有ai个。

  两个人轮流决策,决策分为两种:

   1.选择糖果数最多的一堆糖果,并把这堆糖全吃了。

   2.在每堆非空的糖果堆里拿一颗糖吃掉。

  吃掉最后一颗糖的人输。问你先手必胜还是先手必败。

  n100000

题解

  又是一个打表结论题。

  先把ai从大到小排序。

  设fi,j为删掉前i大,每堆删掉j个后是先手必胜还是先手必败。先把所有的fi,j算出来。

  如果都删完了,就先手必胜。

  打个表可以发现,一条斜线上的结果相同。

  这个结论还是挺好证的。这里就不证了。

  这里写图片描述

  直接找到(0,0)对应的是哪个点(i,i),算出这个点到上方和右方轮廓的距离,只要有一个是偶数,就先手必胜。

  时间复杂度:O(n)

代码

#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<ctime>#include<utility>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;int a[100010];int main(){#ifdef DEBUG    freopen("b.in","r",stdin);    freopen("b.out","w",stdout);#endif    int n;    int i;    scanf("%d",&n);    for(i=1;i<=n;i++)        scanf("%d",&a[i]);    sort(a+1,a+n+1,greater<int>());    int ans;    a[0]=a[1];    for(i=0;i<=n;i++)        if(a[i+1]<=i)        {            ans=(a[i]-i)&1;            int j=i+1;            while(j<=n&&a[j]==i)                j++;            if((j-i+1)&1)                ans=1;            break;        }    if(ans)        printf("First\n");    else        printf("Second\n");    return 0;}
原创粉丝点击