[poj 3537]Crosses and Crosses(博弈论)】的更多相关文章

题意: 给1*n的格子,轮流在上面叉叉,最先画得3个连续叉叉的赢.问先手必胜还是必败. 分析: 求状态的grundy值(也就是sg值),详细怎么求详见代码.为什么这么求要自己想的,仅仅可意会(别人都说去看game theory,呵呵). 代码: //poj 3537 //sep9 #include <iostream> #include <set> using namespace std; int grundy[2048]; int h[2048]; int get_grundy(…
博弈论 相当于放了x的位置,左右4格都不能再放x了,谁无处可放就输. n<=2000 直接枚举后继状态,暴力求SG函数即可. 例: 0000000->x..0000 / .x..000 / ..x..00 / 0..x..0 / 00..x.. 记忆化搜索写挂了……还是顺序DP靠谱= =(跟S-Nim类似的写法,暴力求SG函数) Source Code Problem: User: sdfzyhy Memory: 692K Time: 141MS Language: G++ Result: A…
Crosses and Crosses Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2237 Accepted: 821 Case Time Limit: 2000MS Description The game of Crosses and Crosses is played on the field of 1 × n cells. Two players make moves in turn. Each move the…
                  Crosses and Crosses Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4049   Accepted: 1586 Case Time Limit: 2000MS Description The game of Crosses and Crosses is played on the field of 1 × n cells. Two players make moves…
Crosses and Crosses Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3063   Accepted: 1196 Case Time Limit: 2000MS Description The game of Crosses and Crosses is played on the field of 1 × n cells. Two players make moves in turn. Each mov…
Crosses and Crosses poj-3537 题目大意:给定一个1*n的网格,每次往格子内填一个$\times$,连续的三个即可获胜. 注释:$1\le n\le 2000$. 想法:我们先尝试往里面填一个$\times$. 我们发现对于先手和后手来讲,与那个$\times$相邻的格子都不能动. 所以就相当于整个游戏被分成了3个游戏,中间的是一个$\times$和两个空格. 发现中间的游戏先手必败,故中间的游戏的SG为0. 即:只需要求左右的SG值,爆搜即可. 最后,附上丑陋的代码.…
长为n的一列格子,轮流放同种棋子,率先使棋子连成3个者胜. 可以发现每次放一个棋子后,后手都不能放在[x-2,x+2]这个区间,那么相当于每次放棋将游戏分成了两个,不能放棋者败. 暴力求SG即可 /** @Date : 2017-10-14 22:50:13 * @FileName: POJ 3537 multi-sg 暴力SG.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https:…
POJ.1067 取石子游戏 (博弈论 威佐夫博弈) 题意分析 简单的威佐夫博弈 博弈论快速入门 代码总览 #include <cstdio> #include <cmath> #include <algorithm> using namespace std; int main() { int n,m; while(scanf("%d %d",&n,&m) != EOF){ if( n > m) swap(n,m); doubl…
题目:http://poj.org/problem?id=3537 题意:给你n个格子,两个人依次在n个格子的任意空位置画"X",谁如果画了一个后,3个X连在了一起,那么那个人就获胜了.问是先手胜还是后手胜 分析: 胜利的上一个状态肯定是_XX_或者_X_X_,又因为每个人都是聪明的,也就是说如果一个人在i位置画了一个X,那么另一个人就不能在[x-2,x+2]这段区间里面画X,因为如果在这里画了个X,那么另一个人下一手就能连成三个X. 也就是说每次画个X,以它为中心的5个格子都不能再画…
思路:每次画X之后都会形成2个子游戏,即i-3和n-i-2. 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<cstring> using namespace std; ]; int getsg(int n) { ) ; ) return sg[n]; ]={}; ;i<…
题目链接 \(Description\) 有一个一行n列的棋盘,每个人每次往上放一个棋子,将三个棋子连在一起的人赢.问是否有必胜策略. \(Solution\) 首先一个人若在\(i\)处放棋子,那么另一个人就不能在\(i-2,i-1,i+1,i+2\)处放石子,这样会使对方赢. 那么可以看做:在\(i\)处放棋子后,另一个人不能选择\(i-2,i-1,i+1,i+2\)处放石子,不能放的人输. 可以联想到Nim游戏,一个人取一个石子,另一个人可取石子\(-2\):同时是产生两个局面 即1*n的…
[题目链接] http://poj.org/problem?id=3537 [题目大意] 在一个1*n的方格纸上下棋,谁先连三子谁就赢了,问必胜的是谁. [题解] 我们发现对于一个n规模的游戏.在i位置下棋就能将游戏拆分为i-3和n-i-2两个游戏 对于可拆分的游戏,其sg函数为拆分后游戏sg值的异或和,因此我们用记忆化搜索来记录sg值. [代码] #include <cstdio> #include <cstring> using namespace std; int n,sg[…
题目链接 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ]; int get_sg(int n) { ) ; ) return sg[n]; ]; //莫名其妙! //vis[]数组要声明在函数里,如果放外面会WA memset(vis,,sizeof(vis)); ;i<=n;i++) vis[get_sg(n-i-)^get_sg(i-)]=; //子局面异…
传送门 我也不知道为什么枚举vis必须加上一个边界才能A 以后还是都加上吧 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; ; inline int read(){ ,f=; ;c=getchar();} +c-';c=getchar();} return x*f;…
题目:在1*n 的棋盘里面,A和B都在里面画叉 , 如果谁可以画了一个叉后,可以连成3个叉,那谁胜利 : 分析: 首先考虑如果我在玩游戏,我最希望对手可以画出-x-x or  -xx-   ,  这种情况 ,也就是说玩家就一定不可画成这样给对手制造机会 :  那可以当成画了一个叉后 就分成了 (x-3) , (x-2-i)  ,两个游戏 ,那我们可以根据SG的性质来解决这种分解游戏的游戏 #include<stdio.h> #include<string.h> //注意 S数组要按…
题意: 1 × n 个格子,每人每次选一个格子打上叉(不得重复),如果一个人画完叉后出现了连续的三个叉,则此人胜. 给n,判断先手胜还是先手败. 思路: 假设选择画叉的位置是i,则对方只能在前[1,i-3]中或[i+3,n]中选择画叉.子问题出现. 根据SG的定义,即可求出SG(N).看代码. 代码: int sg[2005]; int n; int dfs(int n){ if(n<0) return 0; if(sg[n]!=-1) return sg[n]; bool g[2005] =…
大意: 给定一个\(1 * n\)的棋盘,你和对手轮流在上面画"X" 当出现三个连续的X时,最后一步操作的人胜利 不难发现,在棋盘中画了一个X之后 问题等价于两个一样的子游戏 然后暴力求\(sg\)函数即可 复杂度\(O(n^2)\) #include <bitset> #include <cstdio> #include <cstring> #include <iostream> using namespace std; #define…
poj.org/problem?id=3537 (题目链接) 题意 给出一个1*n的棋盘,每次可以选择一个没被标记过的点打标记,若经过某一步操作使得出现3个连续的标记,则最后操作的人获胜.问是否存在先手必胜策略. Solution 我们可以很快发现,若给x位置打上标记,那么棋盘就被分成了2份,分别是x-3以及n-x-2,于是${sg[n]=mex\{sg[x-3]~XOR~sg[n-x-2]}\}$,1<=x<=n.因为n<=2000,直接暴力求解sg函数即可. 代码 // poj353…
http://poj.org/problem?id=2348 顺便说,必应翻译真的好用,比谷歌翻译好用100倍. 很难判断这道题的具体博弈类型. 有两种写法,一种是找规律,一种是推理得到关系后循环(或递归)处理.两种写法都能在题目下面的discuss中找到. 1.找规律,我在这里直接复制了discuss中大神算出的sg函数表(在考试中这种写法是很值得借鉴的,这里就体现出代码能力的重要了,找规律天下第一!). 我算了一下前 30 × 30 的 Sprague-Grundy 函数表,如下: 0 1…
http://poj.org/problem?id=3533 变成三维的nim积..前面hdu那个算二维nim积的题的函数都不用改,多nim积一次就过了...longlong似乎不必要但是还是加上了 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #include<map> #include<…
http://poj.org/problem?id=2425 典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和.仍然是因为看不懂题目卡了好久. 这道题大概有两个坑, 1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了): 2.是n个点的有向无环图边数上限是n^2(re了好久QAQ). 在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快.下一篇大概会写一个小结. 代码 #include<cstdio> #include&l…
http://poj.org/problem?id=2484 1和2时Alice必胜,3时Bob必胜,其他情况下Bob只需要在Alice取过之后取一次将剩下的硬币链平均分为两份,然后Alice怎么取Bob对称着取就可以了. 真是巧妙. 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #include<ma…
思路:无向图,走过的点不能在走.dfs搞定…… 再就是后继中有必败点的为必胜点! 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<cstring> using namespace std; int ans; vector<]; ]; int dfs(int n) { ;i…
思路:SG函数应用!! 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<vector> #include<cstring> using namespace std; ],n; vector<]; int dfs(int now) { ) return sg[now]; ]={}; ;i<p[now].size();i++) vis[dfs(p[now…
简单的SG函数应用!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<vector> using namespace std; ],k,a[]; int getsg(int x) { ) return sg[x]; ]&l…
详见:http://www.cnblogs.com/xin-hua/p/3255985.html 约束条件6 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #include<iomanip> #include<cmath> #define in(x) scanf("%d",&x) using namespace std; ]; int ma…
题目链接 \(Description\) 一个1~INF的坐标轴上有n个棋子,给定坐标Pi.棋子只能向左走,不能跨越棋子,且不能越界(<1).两人每次可以将任意一个可移动的棋子向左移动一个单位.问先/后手会赢或是否无解. \(Solution\) 首先考虑相邻两个棋子 无论一个人怎么移动前边的棋子,后手都能移动后面棋子同样的距离使得这两个棋子间间隔不变(后手可以模仿.但是移动后面的棋子时,后手是不能模仿的) 同时两个棋子局面的终止是两个棋子相邻 不难想到以这两个棋子间距离为石子数做一个Nim游戏…
Calendar Game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2519    Accepted Submission(s): 1438 Problem Description Adam and Eve enter this year's ACM International Collegiate Programming Co…
也就是转换到树形删边游戏,详见 https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1005; int T,n,m,cnt,h[N],w[N],s[N],top; bool v[N],ve[N]; struct qwe { int n…
题目描述 题解: 一道非常简单的$SG$函数应用. 对于一个长度求它的$SG$函数,然后判断是否为$0$即可. 代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; int n,sg[N]; int dfs(int x) { ); if(~sg[x])return sg[x]; }; ;i<=x;i++) tmp[dfs(i-)^dfs(x-i-)]=;…