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. ES6扩展——数值扩展

    1.0o代表八进制 0b代表二进制 ,通过Number()可转为10进制: //0o 0O octanary八进制 //0b 0B binary二进制 console.log(0o16); //14 ...

  2. T-SQL - query03_去重查询|模糊查询|排序|分组|使用函数

    时间:2017-09-29 整理:byzqy 本篇仍以"梁山好汉"数据表为例,介绍几个常用的 T-SQL 查询语句: 去重查询,关键字:distinct 使用通配符模糊查询,关键字 ...

  3. Learning ROS: Getting started with roswtf (检查ROS系统,找出问题)

    本文主要部分来源于ROS官网的Tutorials. roswtf是ROS的检查工具,用于检查ROS安装和运行系统. Checking your installation&Offline mak ...

  4. .NetCore3.1获取文件并重新命名以及大批量更新及写入数据

    using Microsoft.AspNetCore.Mvc; using MySql.Data.MySqlClient; using System; using System.Collections ...

  5. MySQL 常用的聚合函数

    [常用的聚合函数] mysql聚合函数一般用户统计一列值进行计算,然后返回计算结果.一般于分组group by 配合使用. count //统计个数 select count(*) from test ...

  6. tomcat漏洞总结

    描述 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由 ...

  7. PyQT5:信号和槽

    PyQT5:信号和槽 信号和槽 Qt的主要特征之一是它使用信号和插槽在对象之间进行通信. 当潜在的事件发生时,会发出一个信号.插槽是可调用的Python,如果将信号连接到插槽,则在发出信号时将调用该插 ...

  8. 五分钟搞懂MySQL索引下推

    大家好,我是老三,今天分享一个小知识点--索引下推. 如果你在面试中,听到MySQL5.6"."索引优化" 之类的词语,你就要立马get到,这个问的是"索引下推 ...

  9. K8s 系列(四) - 浅谈 Informer

    1. 概述 进入 K8s 的世界,会发现有很多的 Controller,它们都是为了完成某类资源(如 pod 是通过 DeploymentController, ReplicaSetControlle ...

  10. samba网络共享

    1.sanma简介 2. samba安装 #更新源 opkg update #搜索软件包,查看版本 opkg list | grep "samba" #根据查询的版本安装服务器和l ...