题目大意:给定n堆石子,每次可以选择一堆石子,拿走任意个,然后将堆中剩余石子移动任意个到任意一些堆里,不能操作者为输,求是否先手必胜
必败状态为:n为偶数,且将石子数相同的堆两两配对可以配成n2对
例如:
6
1 1 4 4 5 5
这就是一个先手必败的初始状态
证明:
首先证明这个状态是必败的
由于堆可以两两配对,因此无论先手做什么,后手都可以对另一个堆做同样的事情,故先手必败
对于一种其他状态,先手可以用一步将状态变为必败状态,故其他状态下先手必胜
如果初始有奇数堆石子,那么先手可以将最小的堆和第二小的堆配对,第三小的堆和第四小的堆配对,…,然后用最大的堆填补差值,显然一定能填补上;
如果初始有偶数堆石子,那么先手可以将最大的堆和最小的堆配对,第二小的堆和第三小的堆配对,第四小的堆和第五小的堆配对,..,用最大的堆多出来的部分填补差值,显然也一定能填补上
故其他状态先手必胜
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n;
char s[M];
string a[M];
int main()
{
int i;
cin>>n;
if(n&1)
return cout<<"first player"<<endl,0;
for(i=1;i<=n;i++)
{
scanf("%s",s+1);
a[i]=s+1;
}
sort(a+1,a+n+1);
for(i=1;i<=n;i+=2)
if(a[i]!=a[i+1])
return cout<<"first player"<<endl,0;
return cout<<"second player"<<endl,0;
}
时间: 2024-10-07 00:22:03