题目链接
题目大意
A和B在玩一个石子游戏,有n堆石子,每堆石子有ai个石子,A和B轮流取石子,每次只能取一个,当一个人输了游戏是一下两种情况之一:
1.没有石子可取的时候
2.当当前游戏者取完石子后有两堆石子的数量是一样的
问他们都用最优的策略,A是先手,问比赛的结果
解题思路
我们用cnt[x]记录石子数为x的有多少堆。
那么当先手第一步必败的情况有:
1.cnt[0] >=2
2.cnt[x]>=3
3.cnt[x]>=2&&cnt[y]>=2
4.cnt[x]>=2&&cnt[x-1]>=1
如果以上情况都没有出现,那么我们考虑最终的状态:我们想要没有两堆石子有相同的石子数,所以最终的状态为n堆石子的数量为0到n-1。我们把这些石子从小到大排序,依次减去0到n-1,剩下的石子是A和B可以取的石子。那么当可取石子数位偶数的时候,先手必败,否在后手必败
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
const int N=1e5+5;
int a[N],n;
map<int,int>ma;
int main()
{
int flag=0,k=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
ma[a[i]]++;
if(ma[a[i]]>2)//第二种情况
flag=1;
if(ma[a[i]]==2)//第三种情况
{
if(k==0)
k=a[i];
else
flag=1;
}
}
if(ma[0])//第一种情况
if(ma[0]>1)
flag=1;
for(int i=1;i<=n;i++)
{
if(ma[a[i]]>1)//第四种情况
{
if(ma[a[i]-1])
flag=1;
}
}
if(flag)
printf("cslnb\n");
else
{
long long sum=0;
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
sum+=(long long)(a[i]-i+1);
if(sum%2)//判断最终状态
printf("sjfnb\n");
else
printf("cslnb\n");
}
return 0;
}