hdoj 1729 Stone Games(SG函数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1729

看了题目感觉像Nim,但是有范围限制,有点不知道SG函数该怎么写

看了题解,最后才明白该怎么去理解 。

首先进行对s和c进行分类,

1、c = 0 的时候,无论怎样都填不满,直接跳过;

2、c = s 的时候,先手必败,即是P态;

3、c < s 的时候,可以分为两种情况:

1)c^2 + c < s 的时候,递归

2)c^2 + c > s 的时候,先手必胜,即N态

1 int mex(int s, int c){
2     if( c == 0 || s == c)
3         return 0;
4     int q = sqrt(s);
5     while( q+q*q >= s)
6         q--;//最大的不能一次填满的数
7     if(c > q) return s-c;
8     else return mex(q,c);
9 }

主要的理解难点就是 mex(s,c)和mex(k,c)为什么是等价的,个人是这么理解的,

当跑到第一个q+q*q<s的时候,如果c>q,那么可以一次填满,

但如果c<q,不可能一次填满,此时可以分割成两个事件,mex(c,k)和mex(s,k),

其中对于mex(s,k),mex(s,s) 是先手必败,即P态,mex(s,k+1)...mex(s,s-1)都是先手必胜,即N态,

所有移动都导致N态局面的是P态,所以显然mex(s,k)是P态,那么mex(s,k)显然与mex(k,c)等价

 1 #include<stdio.h>
 2 #include<cmath>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXN = 1000010;
 6 int mex(int s, int c){
 7     if( c == 0 || s == c)
 8         return 0;
 9     int q = sqrt(s);
10     while( q+q*q >= s)
11         q--;//最大的不能一次填满的数
12     if(c > q) return s-c;
13     else return mex(q,c);
14 }
15 int main(){
16     int N;
17     int ans;
18     int s, c;
19     int T = 0;
20     while(~scanf("%d",&N)&&N){
21         ans  = 0;
22         for(int i = 0; i < N; ++i){
23             scanf("%d%d",&s,&c);
24             ans = ans^mex(s,c);
25         }
26         printf("Case %d:\n",++T);
27         if(ans)
28             puts("Yes");
29         else
30             puts("No");
31     }
32 }
时间: 2024-08-27 20:30:51

hdoj 1729 Stone Games(SG函数)的相关文章

hdu 1729 Stone Game SG函数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1729 题意:2个玩家,有N个箱子,每个箱子的大小是Si,游戏开始前,就有一些石子在这些箱子里了. 游戏者轮流选择箱子,然后把石子放入箱子里.并且放入的石子数量不能大于原来箱子里就有的石子的数量的平方. 比如说,一个箱子里已经有了3个石头,则可以放1-9个石头(小于箱子的容量). 当轮到某人时,不能再放石子则为输. 问能否找到一种策略使先手必赢. 学习了一下SG函数. 在公平的组合游戏中(游戏规则对于

HDU1729 Stone Game (SG函数)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1729 题意: 又n个盒子,每个盒子的可以放 S个石头,里面已经有的石头的个数为C: 每次可以放的石头的个数不超过C*C.先手胜的输出Yes,后手胜输出No. 分析: 必败的状态很好找 当C + C * C < S && (C + 1) + (C + 1) * (C + 1) > = S; 然后我们对于每一组(c,s)来寻找他的必败状态. 枚举for(i = 1 ; i + i *

Light OJ 1296 - Again Stone Game (博弈sg函数递推)

F - Again Stone Game Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Description Alice and Bob are playing a stone game. Initially there are n piles of stones and each pile contains some stone. Alice stars the

UVA 11927 - Games Are Important(sg函数)

UVA 11927 - Games Are Important 题目链接 题意:给定一个有向图,结点上有一些石头,两人轮流移动石头,看最后谁不能移动就输了,问先手还后手赢 思路:求出每个结点的sg函数,然后偶数个石头结点可以不用考虑,因为对于偶数情况,总步数肯定能保证是偶数,所以只要考虑奇数情况的结点 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <vector&g

HDOJ 5724 博弈SG函数

链接: http://blog.csdn.net/tc_to_top/article/details/51958964 题意: n行20列的棋盘,对于每行,如果当前棋子右边没棋子,那可以直接放到右边,如果有就跳过放到其后面的第一个空位子,A先操作,最后谁无法操作则输,给定每行棋子状态,问先手是否必胜 题解: 组合博弈问题,直接sg函数,因为列只有20,可以状压搞,枚举每个状态,找到该状态下可行的操作然后标记 代码: 31 int sg[1 << 21]; 32 int vis[21]; 33

hdu 1729 Stone Game

Stone Game HDU - 1729 题意: 给定n个箱子,每个箱子的容量为si,每个箱子里最初有ci个石子,每次放入石子不能超过放入前的石子数的平方,谁无法继续放入石子就算输. /* 这是个SG函数的基础题?并不是的吧.. 求一个t使t+t*t=si,那么 1.当ci>t时,是必胜态,可以一次性放满箱子,即(si,si). 2.当ci==t时,即便只放一个,下一个状态t+1+(t+1)*(t+1)一定能放满箱子必胜,所以ci==t这个状态必败. 3.当ci=si-t,同样的方法判断必胜必

SG函数入门

SG函数入门 必胜点与必败点 概念 P点:必败点,换句话说,就是在双方都选择最优策略的情况下,谁处于此状态谁必败. N点:必胜点,换句话说,就是在双方都选择最优策略的情况下,谁处于此状态谁必胜. 性质 1.所有的终结点都是必败点P. 2.从任意的必胜点N进行操作,至少有一种方式到达一个必败点. 3.从任意的一个必败点P进行操作,只可能到达必胜点N. 我们研究必胜点与必败点的目的是以此为题来简化博弈的情况,有助于我们分析策略.通常我们分析必胜点和必败点都是以终结点为起始点进行逆序分析. 我们以一道

Nim 游戏、SG 函数、游戏的和

Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于"Impartial Combinatorial Games"(以下简称ICG).满足以下条件的游戏是ICG(可能不太严谨):1.有两名选手:2.两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动:3.对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作.以前的任何操作.骰子的点数

(转载)--SG函数和SG定理【详解】

在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: 1.所有终结点是 必败点 P .(我们以此为基本前提进行推理,换句话说,我们以此为假设) 2.从任何必胜点N 操作,至少有一种方式可以进入必败点 P. 3.无论如何操作,必败点P 都只能进入 必胜点 N. 我们研究必胜点和必败点的目的时间为题进行简化,有助于