题解 [SDOI2009]E&D/染色游戏/Moving Pebbles
E&D
题目大意
给出 \(2n\) 堆石子,\(2i-1\) 和 \(2i\) 为一组。每次可以选择一组删掉其中一堆,然后从同一组另外一堆选出若干石子放入被删掉的堆内,需要保证每个时刻每堆石子大小 \(\ge 1\)。不能操作的人就算输。问先手是否有必胜策略。
\(n\le 10^4\)
思路
首先我们发现我们肯定是对一组找出 sg 值,然后异或起来,于是问题就是如何求出 \(sg(x,y)\),然后我们打表之后发现:

然后你通过 oies 发现 \(sg(n,m)\) 等于 \((n-1)|(m-1)\) 二进制下第一位为 0 的编号。
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define MAXN 20005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int t,n,val[MAXN];
int fuckSG (int n,int m){
if (n % 2 && m % 2) return 0;
int sum = (n - 1) | (m - 1);
for (Int i = 0;;++ i) if (!(sum >> i & 1)) return i;
}
signed main(){
read (t);
while (t --> 0){
read (n);int sum = 0;
for (Int i = 1;i <= n / 2;++ i){
read (val[i * 2 - 1],val[i * 2]);
sum ^= fuckSG (val[i * 2 - 1],val[i * 2]);
}
puts (sum ? "YES" : "NO");
}
return 0;
}
染色游戏
题目大意
一个 \(n\times n\) 的棋盘, 每次可以选择一个连通块,并把其中的硬币全部翻转,但是需要满足存在一个 硬币属于这个连通块并且所有其他硬币都在它的左上方(可以正左方也可以正 上方),并且这个硬币是从反面向上翻成正面向上。dongdong 和 xixi 轮流操作。如果某一方无法操作,那么 ta 就输了。dongdong 先进行第一步操作,假设双方都采用最优策略。问 dongdong 是否有必胜策略。
\(n\le 100\)
思路
首先考虑一维的翻石子游戏,我们有定理:
局面的 sg 值为每个正面朝上的硬币的 sg 函数 nim 和
于是问题就是如何求出 \(sg(n,m)\),然后你打表后发现:
\]
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define MAXN 205
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int t,n,m;
bool f[205];
char s[MAXN];
int lowbit (int a){return a & (-a);}
int SG (int a,int b){
if (a == 1 || b == 1) return (int)log2 (lowbit (a + b - 1));
else return a + b - 2;
}
signed main(){
read (t);
while (t --> 0){
read (n,m);
memset (f,0,sizeof (f));
for (Int i = 1;i <= n;++ i){
scanf ("%s",s + 1);
for (Int j = 1;j <= m;++ j) if (s[j] != 'H') f[SG (i,j)] ^= 1;
}
int sum = 0;
for (Int i = 0;i <= 200;++ i) sum |= f[i];
puts (!sum ? "=_=" : "-_-");
}
return 0;
}
Moving Pebbles
题目大意
给出 \(n\) 堆石子,每次可以选择一堆石头,拿掉其中至少一个,然后可以移动若干个石子到任意一个石子堆内。
\(n\le 10^5\)
思路
这个题目有2个结论:
当 \(n\) 为奇数时先手必胜
当 \(n\) 为偶数时当且仅当每种石子堆数出现偶数次先手必败,否则先手必胜
首先我们可以清楚:当只有两堆且两堆石子数相同时,先手必败。因为后手可以做对称操作。然后结论 1 其实可以举个例子,当 \(n=3\) 时,因为我只要让后手遇见 2 堆相同情况即可。然后你发现删掉删掉最大堆一定可以做到。然后推广一下你就发现 \(n\) 为奇数的时候都可以做到。
结论 2 是因为奇数堆必胜,那当前为偶数堆的时候一定想让对手取完第一堆。这种时候当且仅当所有堆数都为 1 的情况出现。那么说白了就是一个 nim 博弈,如果满足每种石子堆数出现偶数那么 nim 和就为 0,先手必败,反之先手必胜。
感觉这个题还是很妙的,只是校内 OJ 数据水了一点导致很多人都过了。
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define MAXN 100005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int n,a[MAXN];
signed main(){
read (n);
for (Int i = 1;i <= n;++ i) read (a[i]);
if (n & 1){
puts ("first player");
return 0;
}
else{
sort (a + 1,a + n + 1);
for (Int i = 1;i <= n;i += 2)
if (a[i] != a[i + 1]){
puts ("first player");
return 0;
}
puts ("second player");
}
return 0;
}
题解 [SDOI2009]E&D/染色游戏/Moving Pebbles的更多相关文章
- Bzoj 1982: [Spoj 2021]Moving Pebbles 博弈论
1982: [Spoj 2021]Moving Pebbles Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 130 Solved: 88[Submi ...
- BZOJ1982 [Spoj 2021]Moving Pebbles 【博弈论】
题目 Moving Pebbles Two players play the following game. At the beginning of the game they start with ...
- 【BZOJ1434】[ZJOI2009]染色游戏(博弈论)
[BZOJ1434][ZJOI2009]染色游戏(博弈论) 题面 BZOJ 洛谷 题解 翻硬币的游戏我似乎原来在博客里面提到过,对于这类问题,当前局面的\(SG\)函数就是所有反面朝上的硬币单一存在时 ...
- [SPOJ2021] Moving Pebbles
[SPOJ2021] Moving Pebbles 题目大意:给你\(N\)堆\(Stone\),两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就 ...
- BZOJ 1982 [Spoj 2021]Moving Pebbles(博弈论)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1982 [题目大意] 两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头, 然后移动任意 ...
- [JSOI2015]染色游戏
Description 棋盘是一个n×m的矩形,分成n行m列共n*m个小方格. 现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定: 1.棋盘的每一个小方格既可以染色(染 ...
- 题解 P5038 [SCOI2012]奇怪的游戏
题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...
- BZOJ 1982: [Spoj 2021]Moving Pebbles [博弈论 对称]
给你N堆Stone,两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就输了... 以前在poj做过已经忘记了... 构造对称,选最多的一堆往其他堆分 ...
- BZOJ 1434: [ZJOI2009]染色游戏
一开始想这不$SG$裸题...然后发现100组数据...然后发现连通块是任意的求$SG$貌似要暴力枚举.... 然后想了一下1维,手动打表,每次就是队当前所有异或后缀和求$mex$,好像就是$lowb ...
随机推荐
- win修改host问及那
- 解决 conda tensorflow failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED
参考解决方案1:https://stackoverflow.com/questions/38303974/tensorflow-running-error-with-cublas 参考解决方案2:ht ...
- TensorFlow-Slim 简介+Demo
github介绍:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim 基于slim实现的yolo- ...
- [源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区
[源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区 目录 [源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区 0x00 摘要 0x01 前言 1.1 P ...
- 太空大战-GUI实现(1)
1.复习GUI后,第一天实现的效果 2. 项目实现思路 基本的窗口界面实现就不讲了,源码都看得懂的,这里只说其中比较重要的几个功能的实现. 面板的绘制(所有图形的绘制) 首先,需要在GamePanel ...
- 记一次 .NET 某机械臂智能机器人控制系统MRS CPU爆高分析
一:背景 1. 讲故事 这是6月中旬一位朋友加wx求助dump的故事,他的程序 cpu爆高UI卡死,问如何解决,截图如下: 在拿到这个dump后,我发现这是一个关于机械臂的MRS程序,哈哈,在机械臂这 ...
- Java最大栈深度有多大?-从一道面试题开始学习JVM
一.问题:Java最大支持栈深度有多大? 1.分析 有JVM的内存结构我们可知: 随着线程栈的大小越大,能够支持越多的方法调用,也即是能够存储更多的栈帧: 局部变量表内容越多,那么栈帧就越大,栈深度就 ...
- 五分钟搞懂MySQL索引下推
大家好,我是老三,今天分享一个小知识点--索引下推. 如果你在面试中,听到MySQL5.6"."索引优化" 之类的词语,你就要立马get到,这个问的是"索引下推 ...
- python 常用的文件操作命令
一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 2.返回指定目录下的所有文件 ...
- PULPino datasheet中文翻译并给了部分论文注释(前四章:Overview、Memory Map、CPU Core、Advanced Debug Unit)
参考: (1).PULPino datasheet:https://github.com/pulp-platform/pulpino/blob/master/doc/datasheet/datashe ...