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)\),然后你打表后发现:

\[sg(n,m)=\left\{\begin{array}{l}\text{lowbit}(n+m-1),n=1\vee m=1\\2^{n+m-2},\text{otherwise}\end{array}\right.
\]

\(\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个结论:

  1. 当 \(n\) 为奇数时先手必胜

  2. 当 \(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的更多相关文章

  1. Bzoj 1982: [Spoj 2021]Moving Pebbles 博弈论

    1982: [Spoj 2021]Moving Pebbles Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 130  Solved: 88[Submi ...

  2. BZOJ1982 [Spoj 2021]Moving Pebbles 【博弈论】

    题目 Moving Pebbles Two players play the following game. At the beginning of the game they start with ...

  3. 【BZOJ1434】[ZJOI2009]染色游戏(博弈论)

    [BZOJ1434][ZJOI2009]染色游戏(博弈论) 题面 BZOJ 洛谷 题解 翻硬币的游戏我似乎原来在博客里面提到过,对于这类问题,当前局面的\(SG\)函数就是所有反面朝上的硬币单一存在时 ...

  4. [SPOJ2021] Moving Pebbles

    [SPOJ2021] Moving Pebbles 题目大意:给你\(N\)堆\(Stone\),两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就 ...

  5. BZOJ 1982 [Spoj 2021]Moving Pebbles(博弈论)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1982 [题目大意] 两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头, 然后移动任意 ...

  6. [JSOI2015]染色游戏

    Description 棋盘是一个n×m的矩形,分成n行m列共n*m个小方格. 现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定: 1.棋盘的每一个小方格既可以染色(染 ...

  7. 题解 P5038 [SCOI2012]奇怪的游戏

    题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...

  8. BZOJ 1982: [Spoj 2021]Moving Pebbles [博弈论 对称]

    给你N堆Stone,两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就输了... 以前在poj做过已经忘记了... 构造对称,选最多的一堆往其他堆分 ...

  9. BZOJ 1434: [ZJOI2009]染色游戏

    一开始想这不$SG$裸题...然后发现100组数据...然后发现连通块是任意的求$SG$貌似要暴力枚举.... 然后想了一下1维,手动打表,每次就是队当前所有异或后缀和求$mex$,好像就是$lowb ...

随机推荐

  1. Ubuntu 设置不更新某些软件

    方法来自:https://blog.csdn.net/zhrq95/article/details/79527073 保持某软件版本不变,如我wps-office,(已测有效@Ubuntu 16.04 ...

  2. Python中的多线程编程

    前言: 线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元) 它被包含在进程之中,是进程中的实际运作单位 一个进程中可以并发多个线程每条线程并行执行不同的任务 (线程是进程中的一个实体,是 ...

  3. MySQL——优化

    MySQL数据库优化: 1.优化角度 安全: 数据可持续性 性能: 数据的高性能访问 2.优化范围(优化顺序---->) (1)存储.主机和操作系统: 主机架构稳定性 I/O规划及配置 swap ...

  4. Linux基础命令(基于CentOS7)

    1.帮助相关命令 man 查看普通命令的帮助 --help 只能查看内置命令 info 查看一个命令的更多信息 type 查看是否为内置命令 2.关机重启 shutdown -h 关机 -r 重启 - ...

  5. openswan框架和编译时说明

    刚开始学习openswan项目代码时,自己尝试了在虚拟机上编译.安装.运行openswan代码,由于当时刚开始学习openswan代码,因此对于其构成并不清楚,在编译.运行过程中有了问题,基本是通过百 ...

  6. IDE集成管理Tomcat的基本原理

    知道IDE是怎样控制Tomcat的,对更清晰地理解Java Web的执行过程有帮助.在此以IntelliJ IDEA为例,简要描述一下IDE集成管理Tomcat的基本原理. 首先是两个重要的环境变量: ...

  7. 远程线程注入DLL

    远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...

  8. python中的getpass模块问题,在pycharm中不能继续输入密码

    python中getpass模块   在pycharm中运行下面的代码: 1 import getpass 2 name = input('请输入你的名字:') 3 passwd = getpass. ...

  9. Linux上安装服务器监视工具,名为pyDash。

    pyDash – A Web Based Linux Performance Monitoring Tool 你可以通过以下命令来判断是否已安装: pip --version # Python2.x ...

  10. nodejs安装 Later version of Node.js is already installed. Setup will now exit 及 node与npm版本不符

    暴力删除nodejs导致无法重新安装  Later version of Node.js is already installed. Setup will now exit 1.电脑全局搜索nodej ...