扯在前面

我们老师刚讲过的题目,很考验思维,本蒟蒻WA了十发才过,然后看到题解里只是指出了特殊情况没多解释,可能有人看不懂,特来分享一下

首先题目就很有意思,思考的过程也很有趣,想把所有情况思考全思考对是件很不容易的事


正文

题意:

两人取n堆数量不定的石子,当某一方取完后剩下了两堆一样的或本轮无石子可取(当前石子数为0),则失败。问给出石子各堆的数量,求先手胜还是后手胜。

分析:

首先,站在博弈论的角度,或者说把自己当做参与者,思考一下什么情况下是对自己最有利的,也就是说什么情况下自己必胜

然后抱着这样的心态,我们可以手玩几组样例。

我们就可以知道

  1. 若场上有两堆石子,一堆数量多一堆数量少,那我们宁可取少的,因为那样出现取完后两堆相同的概率最低;

  2. 当两边都这样想时,就会不停取,一直取到一种极端情况,那就是每堆石子的数量是以一递增的,那时游戏就结束了,因为不管再怎么取,都会出现两堆相同数量的石子(两堆0也是);

  3. 当场上已经有两堆相同的石子时,下一次操作的人必取两堆其中之一,因为他如果不取,取完后这两堆相同,他就输了;

  4. 若刚刚那人取完后,场上仍存在两堆相同的,他还是输了,即当时还存在一堆石子数量是刚刚那两堆数量减一或场上存在另外两堆以上数量相同但与这两堆数量不同的石子

  5. 若场上存在三堆及以上石子时,先手无论怎么取,都会输,原因同上

然后可得出情况如下可以判断某方必胜:

  1. 场上石子数已经是按1递增的
  2. 场上存在三堆及以上石子相等
  3. 场上存在两堆石子相同且还有一堆石子数比这两堆少一
  4. 场上存在两堆0

这些先判断出来,剩下的统计原来的石子总数与极端情况的石子总数之差,若为偶数则后手赢,反之则先手赢

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#define maxn 1000100 using namespace std; int n,a[maxn],tot,cnt,js; int main(){
scanf("%d",&n);
// if(n==1 &&a[1]==0){
// cout<<"cslnb";
// return 0;
// }
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
tot+=a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
if(a[i]==a[i+1]) js++;
}
if(js>=2){
cout<<"cslnb";//有两堆以上一样的时后手必赢
return 0;
}
if(js==1){
for(int i=1;i<=n;i++){
if((a[i]==a[i+1] &&a[i-1]+1==a[i] && i!=1) ||(a[i]==a[i+1] &&a[i]==0)){
cout<<"cslnb";//此时先手无所下手,后手赢
return 0;
}
}
}
// if(n==2 &&((a[1]==1&&a[2]==0) ||(a[2]==1 &&a[1]==0))){
// cout<<"sjfnb";
// return 0;
// }
for(int i=1;i<=n;i++){
cnt+=i;
}
cnt-=n;
if(tot-cnt==0){
cout<<"cslnb";
return 0;
}
if((tot-cnt)%2==0) cout<<"cslnb";
else cout<<"sjfnb";
return 0;
}

请批评指正

CF1190B的更多相关文章

  1. 题解 CF1190B 【Tokitsukaze, CSL and Stone Game】

    思路: 首先题目告诉我们,一次只能删去一个石子.当然有翻译时会注意,但是看英文题时总是容易忽略.. 先排序. 然后,你会发现,有些情况是一开始就输的,具体情况如下: 有两个 两个相等非零数.(a[x] ...

随机推荐

  1. 【C++】C++之类型转换

    作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14209848.html 目录 一.前言 二.static_cast 2.1 使用场景 2.2 实例 三.dyna ...

  2. Q227 Basic Calculator II

    /* 看的答案,设置一个符号变量记录这个数前边的符号是什么,不同的符号进行不同的操作.这点自己想到了. 没想到的是由于乘除相当于一个优先级高的线程,所以要先处理,还有存取前一个乘数或者分子,应该怎么办 ...

  3. Linux嵌入式学习-USB端口号绑定

    由于ubuntu USB设备号为从零开始依次累加,所以多个设备每次开机后设备号不固定,机器人每次开机都要蛋疼的按顺序插, 在网上找到一种方法:udev的规则 udev的规则说明,可以参考博客说明:ht ...

  4. 所有CSS字体属性

    font(在一个声明中设置所有的字体属性) font-family(指定文本的字体系列) font-size(指定文本的字体大小) font-style(指定文本的字体样式) font-variant ...

  5. WEBSERVICE之CXF框架开发webservice

    之前学习了使用jdk开发webservice服务,现在开始学习使用框架(cxf)开发webservice. 1.准备工作 A.使用cxf开发webservice服务,需要用到apache-cxf-3. ...

  6. Java图片的灰度处理方法

    通过看网上各种大牛的总结,和自己亲身测试总结一下Java图片的灰度处理方法 (1)我们熟知的图片中的像素点有RGB值. (2)图片灰度化的方式大概分为四种,第一种是最大值法(取颜色RGB中的最大值作为 ...

  7. case when then else end用法

        case具有两种格式,简单case函数和case搜索函数 case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略 1.简单函数 CASE sex         WHEN '1 ...

  8. RMI之由浅入深(一)

    0x01.什么是RMI RMI(Remote Method Invocation)即Java远程方法调用,RMI用于构建分布式应用程序,RMI实现了Java程序之间跨JVM的远程通信.顾名思义,远程方 ...

  9. Faceto_object_programdesign

    一面向对象程序设计思想 1 和面向过程关注点不同 过程: 程序执行流程和逻辑 (局部功能) 对象: 程序中的对象 (程序结构) 2 对象 现实世界中的实体和事物 可以看成是一种具有自身属性和功能的构件 ...

  10. Sentinel限流之快速失败和漏桶算法

    距离上次总结Sentinel的滑动窗口算法已经有些时间了,原本想着一口气将它的core模块全部总结完,但是中间一懒就又松懈下来了,这几天在工作之余又重新整理了一下,在这里做一个学习总结. 上篇滑动窗口 ...