AtCoder Grand Contest 002 E - Candy Piles 博弈论
2018-02-11 13:17
363 查看
题意
有n堆糖果,两个人可以轮流选择两种操作中的其中一种:把数量最大的那堆糖果吃掉
把每堆没吃完的糖果各吃掉一颗
吃掉最后一颗糖果的人输,问先手必胜还是后手必胜。
n<=100000,ai<=10^9
分析
一开始看错题了,把第二个操作看成是把其中一堆糖果吃掉一堆,发现不会做。看对题之后,发现还是不会做。。。我们可以把糖果按照数量从大到小排成一排,把一堆糖果看成是数量*1的点阵。
每次可以删掉第一列或第一行,不能操作者输。
设点(x,y)表示删掉了前x列和前y行的状态,1表示先手必胜。
有个结论就是(x,y)的状态和(x-1,y-1)的状态相同。
因为若(x,y)=0,则不管先手从(x-1,y-1)怎么走,后手都可以走到(x,y)。
若(x,y)=1,则(x-1,y-1)不可能为0。
考虑反证,设(x-1,y-1)=0,那么会得到下面的情况
0 ?
1 1 ?
0 1 0
因为1的后继至少要有一个0,0的后继必须全是1,那么两个问号至少要有一个是1,而又必须全部是0,故矛盾。
剩下的就可以随便搞了。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=100005; int n,a ; bool cmp(int x,int y) { return x>y; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1,cmp); int p; for (int i=1;i<=n;i++) if (i+1>a[i+1]) {p=i;break;} int q=p; while (q<n&&a[q+1]>=p) q++; int tag=0; if (p==q) tag=(a[p]-p)&1; else if (a[p]==p) tag=(q-p)&1; else tag=((a[p]-p)&1)|((q-p)&1); if (tag) puts("First"); else puts("Second"); return 0; }
相关文章推荐
- AtCoder Grand Contest 002 E - Candy Piles
- AtCoder Grand Contest 010 D - Decrementing 博弈论
- AtCoder Grand Contest 002 D - Stamp Rally 并查集+二分答案+倍增
- AtCoder Grand Contest 002 F - Leftmost Ball 动态规划
- AtCoder Grand Contest 002 D - Stamp Rally
- AtCoder Grand Contest 002 D - Stamp Rally
- AtCoder Grand Contest 002 D - Stamp Rally
- AtCoder Grand Contest 014 D - Black and White Tree 博弈论
- AtCoder Grand Contest 010 F - Tree Game 博弈论
- AtCoder Grand Contest 005 E - Sugigma: The Showdown 博弈论+贪心
- 【Atcoder Grand Contest 010】D - Decrementing——博弈论
- AtCoder Grand Contest 018A: Getting Difference 题解
- AtCoder Grand Contest 003 D - Anticube
- AtCoder Grand Contest 020 C - Median Sum (背包问题+bitset )
- AtCoder Grand Contest 016 E - Poor Turkeys 贪心
- AtCoder Grand Contest 006 D - Median Pyramid Hard 二分答案
- Atcoder Grand Contest 021 简要题解
- Atcoder Grand Contest 010 D Decrementing
- [AtCoder Grand Contest 016] D: Xor Replace (agc016d)
- AtCoder Grand Contest 004 C - AND Grid(思路题)