[CF1190B] Tokitsukaze, CSL and Stone Game - 博弈
Description
面前有(n)堆石子,第(i)堆石子有(a_i)颗石头,他们轮流取石子。每一次,取石子的人会选中一个非空的石子堆并取走其中的一颗石子。如果在某个人的回合前所有的石子堆都是空的,或者在他取完后有两堆的石子数量相同(两堆都没有石子也算),则他输掉游戏。
Solution
如果能找到这样的子集,那么一定是必败状态
x,x,x
x,x,y,y
x,x,x-1
0,0
0,1,2,...,n-1
如何证明充分性?
假如当前局面不属于上面任何一种,为了让这种情况保持下去,最后一定会变成 0,1,2,...,n-1 这样子(否则就会出现重复)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100005;
int n;
signed main()
{
map<int, int> mp;
cin >> n;
vector<int> a(n);
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
a[i - 1] = x;
mp[x]++;
}
int flag = 1, cnt = 0;
for (auto [x, y] : mp)
{
if (mp[x] >= 3)
flag = 0;
if (mp[x] >= 2 && mp[x - 1])
flag = 0;
if (mp[x] >= 2)
++cnt;
}
if (mp[0] >= 2)
flag = 0;
if (cnt > 1)
flag = 0;
sort(a.begin(), a.end());
int delta = 0;
for (int i = 0; i < n; i++)
delta += a[i] - i;
if (delta % 2 == 0)
flag = 0;
cout << (!flag ? "cslnb" : "sjfnb") << endl;
}