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 ...
随机推荐
- 如何向Maven仓库(私服)中上传第三方jar包
本文详细介绍如何向maven仓库中上传第三方jar包. 1.在本地maven安装路径中找到conf文件夹下面的setting.xml文件,里面有访问maven仓库的路径和账号.密码: 2.浏览器打开第 ...
- ibatis中$和#的区别
比如当变量name的类型是Stirng时, $name$ 打印出来的是 张三 #name# 打印出来的是 ‘张三’ $ 的作用实际上是字符串拼接 #用于变量替换 那什么时候用$,什么时候 用 # (1 ...
- Codeforces 750 F:New Year and Finding Roots
传送门 首先如果一开始就找到了一个叶子,那么暴力去递归找它的父亲,每次随机一个方向(除了已知的儿子)走深度次,如果走到了一个叶子就不是这个方向 (设根的深度为 \(1\))这样子最后到达深度为 \(3 ...
- css动画笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用servicestack连接redis
引言:作为少有的.net架构下的大型网站,stackoverflow曾发表了一篇文章,介绍了其技术体系,原文链接http://highscalability.com/blog/2011/3/3/sta ...
- GDAL线面互转换(2)
在上一个文章中介绍了线转化为面和面转化为线,其主要的实现思路就是把面中的点取出来构成线,把线中的点取出来构成面,实际上就是一个硬拷贝,无奈客户的实际需求并非如此,客户想要线转面的时候几条相交线构成面, ...
- CentOS7.4 + Hadoop2.7.5安装配置管理(伪分布式)
1. 规划 1.1. 机器列表 NameNode SecondaryNameNode DataNodes 192.168.1.80 192.168.1.80 192.168.1.80 1.2. ...
- 润乾报表与DERBY数据库的创建连接详解
1. 问题概述 1.Derby数据库的创建过程 2.润乾报表连接Derby数据库展现数据 概述: Derby是Apache Software Foundation (ASF)的一个的孵化器项目. ...
- 【个人经历】记自己的第一次GitHub开源代码共享经历
题记: 自己做程序员快三年有余了,感觉自己和刚入职相比确实有了不少进步,当然三年要是不进步那不就傻了吗,有时候我也在想,我在这三年里留下了什么,当然也不是说有多么高尚的想法,就是以后对别人介绍自己的时 ...
- etcd 分布式数据库概念初探
Lease(租约): 其实就是一个定时器.首先申请一个TTL=N的lease(定时器),然后创建key的时候传入该lease,那么就实现了一个定时的key. 在程序中可以定时为该lease续约,也就是 ...