@description@
给定 N 堆糖果,第 i 堆包含 ai 个糖果。
现在两人进行博弈。有两种操作选择:
(1)吃掉包含最多糖果的糖果堆。
(2)每堆吃掉一颗。
吃掉最后一颗糖的人判输,问谁必胜?
@solution@
将 n 个数从大到小排好序,看成一个 n 列的直方图,第 i 列包含 a'i 个格子。
举个例子:对于 5 5 3 2 1 1,可以建立直方图如下:
o o
o o
o o o
o o o o
o o o o o o
那么相当于有一个棋子从 (1, 1) 出发,玩家可以将棋子右/上移一步,走出边界的判输。
然后经过万能的打表找规律,我们可以发现如果 (x, y) 和 (x + 1, y + 1) 同时存在,则两者的 np 状态相同。
不过这个结论利用反证法倒是不难证就是了。。。
于是我们可以先移动到一个点 (x, y) 使得 (x + 1, y + 1) 不存在,注意到从 (x, y) 只能一路向上或右,两种情况都判一判即可。
@accepted code@
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100000;
bool cmp(int x, int y) {return x > y;}
int a[MAXN + 5], N;
int main() {
scanf("%d", &N);
for(int i=1;i<=N;i++)
scanf("%d", &a[i]);
sort(a + 1, a + N + 1, cmp);
for(int i=1;i<=N;i++) {
if( a[i + 1] < i + 1 ) {
int p = (a[i] - i) % 2, q;
for(int j=i;j<=N+1;j++)
if( a[j] < i ) {
q = (j - i - 1) % 2;
break;
}
puts(p & 1 || q & 1 ? "First" : "Second");
break;
}
}
}
@details@
这是什么神仙操作.jpg。
我怎么觉得 E 比 F 难。F 题我好歹会切,E 题完全没有办法。