题目地址
Codeforces Round #573 Tokitsukaze, CSL and Stone Game
http://codeforces.com/contest/1191/problem/D
参考来源
来源于xfx的博客
https://xfx98.github.io/2019/07/13/codeforces-round-573-tokitsukaze-csl-and-stone-game/
题意
这是一道博弈题
题目给了我们两个判断条件:
1、如果有人取了石头后,剩下的石头堆中存在个数一样的石头堆,那么这个人输了。
2、如果有人要取石头的时候,没有石头了,那么这个人输了。
思路
我们先来看先手的必败态:
根据条件1,如果给出的石头堆中,含有两对或者两对以上个数相同的石头堆,那么先手必输。
根据条件1,如果给出的石头堆中,有两堆或以上的石头个数相同,那么先手必输。
根据条件1,如果给出的石头堆中,有两堆或以上的石头个数是0,那么先手必输。
根据条件1,如果有一对相同的石头堆,但是存在比它石头个数小1石头堆,那么先手必输。
而如果石头个数的总和小于n * (0 + n - 1) / 2,那么必定会存在上面先手必输情况。
我们再来看操作的终态:
操作的终态一定会是 0 1 2 3 …… n-1,因为任意操作都会出现两个相同堆。
这样可进行的操作次数便是 sum - n * ( n - 1 ) / 2 。然后我们根据操作次数的奇偶性即可知道谁必赢。
做法
我们先把必败态判断完,然后再去求和看操作次数的奇偶性,即可AC。
代码
c++
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100005];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1;i <= n;i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
int num = 0;
for (int i = 1;i < n;i++)
if (a[i + 1] == a[i])
if ((a[i] == 0) || (i > 1 && a[i - 1] + 1 == a[i]) || ++num > 1)
{
puts("cslnb");
return 0;
}
ll sum = 0;
for (int i = 1;i <= n;i++)
sum += (ll)(a[i] - i - 1);
if (sum % 2)
puts("sjfnb");
else
puts("cslnb");
return 0;
}
java
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedInputStream(System.in));
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pr = new PrintWriter(new BufferedOutputStream(System.out));
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws NumberFormatException, IOException {
long sum = 0;
long n = sc.nextLong();
HashSet<Long> hs = new HashSet<>();
ArrayList<Long> al = new ArrayList<>();
for (int i = 0; i < n; i++) {
long te = sc.nextLong();
sum += te;
if(!hs.add(te)) {
al.add(te);
}
}
for (Long ye : al) {
if(hs.contains(ye-1)||ye==0) {
System.out.println("cslnb");
System.exit(0);
}
}
if (hs.size() < n - 1) {
System.out.println("cslnb");
} else {
sum-=n*(n-1)/2;
if (sum < 0) {
System.out.println("cslnb");
} else if ((sum & 1) == 0) {
System.out.println("cslnb");
} else {
System.out.println("sjfnb");
}
}
}
private static int nextInt() {
try {
st.nextToken();
} catch (IOException e) {
e.printStackTrace();
}
return (int) st.nval;
}
}