2018 - 2019 CTU Open Contest H. Split Game 【SG函数】
H. Split Game
1.0 s
256 MB
standard input
standard output
For a long time, rich clientele of Binary Casino has been requesting a new way to gamble their money. To fulfill their wishes, the director of Binary Casino decided to introduce a new game called Split Your Tokens.
This game is played only when a customer is about to exit the casino. Instead of exchanging tokens won during his visit, he may take up casino's challenge and bet all of his earned tokens on winning this game. Should the customer lose, all of his tokens are lost in favor of the casino.
When the game starts, the customer splits his tokens into NN piles with not necessarily same amount of tokens in each pile. The customer and the casino then exchange turns in this game we denote the customer as the first player and the casino as the second player. Each player in his turn decides which pile he wants to split and chooses a positive integer KK which is smaller than the size of the selected pile. Then the player splits the selected pile into as many piles of size KK as possible. If any tokens remain, they form another pile on their own. A player loses the game when he can not do any more splitting. The customer (first player) always plays first.
The director of Binary Casino is however not sure, whether this game will be profitable for the casino in the long term. Your task is thus to determine, for a given configuration of piles, which player wins when both players play optimally.
The first line contains one integer NN (1≤N≤20001≤N≤2000), the number of piles. The second line contains a sequence of NN integers PiPi (1≤Pi≤20001≤Pi≤2000), PiPi represents the number of tokens in the ii-th pile.
Output a single line with either "First" or "Second", depending on which player wins the game if both play optimally.
3
1 2 3
First
3
1 2 2
Second
题意概括:
给出 N 堆物品, 两个玩家轮流选择将其中一个大小为 M 的堆 分成最多的 大小为 K (K < 当前选择的堆的大小)的堆,若 M%K 有剩余,则剩余的自成一堆。
最后所有堆大小都为 1 时不可再分,不能再分堆的玩家输。
解题思路:
因为SG函数的作用就是把博弈的状态当成一个点,然后形成一张 有向图,后继状态也就是后继结点,通过转移图上结点的状态最后求的起始点的结果。
以往 都是选择某一堆 取走若干 然后留下一堆,所以 结点的后继结点就对应剩下的那个状态。也就是说 把每一堆单独作为一个 NIM游戏,最后再考虑所有堆最后异或的结果。
不过 这里是选择某一堆 然后分成若干个小堆,就相当于又变成了一个 NIM游戏,不过考虑到分成的若干小堆 有相同的 和 不同的两部分,相同的直接判奇偶即可,如果有不同的(即分剩下的)再异或上这种状态即可。也就是先把每一堆作为一个 NIM 游戏,每分一次就又玩一次 NIM 游戏。
AC code:
#include <bits/stdc++.h>
#define inc(i, j, k) for(int i = j; i <= k; i++)
#define rep(i, j, k) for(int i = j; i < k; i++)
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
#define INF 0x3f3f3f3f
#define LL long long
#define MEM(i, j) memset(i, j, sizeof(i));
#define gcd(i, j) __gcd(i, j)
using namespace std;
const int MAXN = 2e5+;
const int MM = 2e3+;
int sg[MAXN];
int vis[MAXN]; void getsg()
{
int cnt, res;
sg[] = ;
MEM(vis, -);
inc(i, , MM){
rep(j, , i){
cnt = i/j;
res = i%j;
if(cnt%) vis[sg[res]^sg[j]] = i;
else vis[sg[res]] = i;
}
int k = ;
while(vis[k] == i && k < MM) k++;
sg[i] = k;
}
} int main()
{
getsg();
int N;
scanf("%d", &N);
int ans = , tp;
while(N--){
scanf("%d", &tp);
ans^=sg[tp];
}
if(ans) puts("First");
else puts("Second");
return ;
}
2018 - 2019 CTU Open Contest H. Split Game 【SG函数】的更多相关文章
- 2018 - 2019 CTU Open Contest E. Locker Room 【后缀数组】
任意门:http://codeforces.com/gym/101954/problem/E E. Locker Room time limit per test 2.0 s memory limit ...
- COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution
COCI 2018/2019 CONTEST #2 T4 T5 Solution abstract 花式暴力 #2 T5 Sunčanje 题意 按顺序给你1e5个长方形(左下角坐标&& ...
- 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结
20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...
- 2018 German Collegiate Programming Contest (GCPC 18)
2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...
- (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)
layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...
- 2019 Multi-University Training Contest 7
2019 Multi-University Training Contest 7 A. A + B = C 题意 给出 \(a,b,c\) 解方程 \(a10^x+b10^y=c10^z\). tri ...
- 2019 Multi-University Training Contest 2
2019 Multi-University Training Contest 2 A. Another Chess Problem B. Beauty Of Unimodal Sequence 题意 ...
- HDU校赛 | 2019 Multi-University Training Contest 6
2019 Multi-University Training Contest 6 http://acm.hdu.edu.cn/contests/contest_show.php?cid=853 100 ...
- HDU校赛 | 2019 Multi-University Training Contest 5
2019 Multi-University Training Contest 5 http://acm.hdu.edu.cn/contests/contest_show.php?cid=852 100 ...
随机推荐
- idea入手配置
一.编码配置 utf-8 二.注释模板(Java Doc) 三.Live Templates 快捷键模板, 如配置logger,(类似 sout)
- Linux CPU使用率的计算
CPU 使用率衡量的是程序运行占用的CPU 百分比.Linux 的CPU 使用率信息可以通过/proc/stat 文件计算得到. proc 文件系统 /proc 文件系统是一个伪 ...
- Java的工厂模式(三)
除了一般的工厂模式之外,还有抽象工厂模式,抽象工厂模式更强调产品族的概念,一个具体工厂生产出来的系列商品都是一个产品族的. 假设我们有两个具体工厂,分别是袋装水果工厂和罐装水果工厂,它们都能生产苹果和 ...
- web开发基础--字节序
字节是网络传输上的最小单位,是web开发中需要了解的一个知识点. 1.有效位 在谈字节序前需要先了解有效位,有效位分为两种:最低有效位(LSB: Least Significant Bit) 和最高有 ...
- MySQL 报错
SELECT COUNT(1) FROM (select tid from teacher where tname like '李%') 1248 - Every derived table must ...
- xamarin.Android 选择本地图片、拍摄图片、剪裁图片
[Activity(Theme = "@style/MyStyleBottom")] public class SelectPicPopupWindow : Activity, I ...
- js异步原理与 Promise
一.Javascript的异步原理 javascript 是单线程语言,所以同一时间只执行一个运算.但有些方法是不能瞬间完成或不可预知何时完成的(如网络请求.settimeout等),为了让它们不对后 ...
- Storm一个executor里运行多个task是为了rebalance
默认情况下下,一个executor运行一个component,即一个task,但有时会指定多个task: 1 builder.setBolt("", new XxBolt()).s ...
- Java中的Number和Math类简单介绍
Java Number类 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等. 实例: int a = 5000; float b = 13.65 ...
- Eigen学习笔记2-Matrix类
在Eigen中,所有的矩阵Matrix和向量Vector都是由Matrix类构造的.向量只不过是矩阵的特殊形式,只有一列(列向量)或者一行. Matrix模板类有6个参数,其中前三个参数是必须的.前三 ...