HDU1847 —— Good Luck in CET-4 Everybody!

题意:n张牌,轮流抓牌,每次抓的牌数是2的幂次,最后抓完牌的胜。(1≤n≤1000)(1\leq n\leq 1000)(1≤n≤1000)
思路:首先写在这个汇总题集的最前面,博弈问题,大致分为三类,① 经典模型 ② SG函数 ③ 找规律,而此题集主要针对的也是此类找规律问题。
对于此题,的确可以用SGSGSG函数解决,但是我们可以先找一下规律,不要着急下手。(实测,SG函数会T…)
此处用W表示Win,F表示Fail。1 - W 、2 - W、3 - F、4 - W、5 - W、6 - F…列的再多一些,就可以明显地发现当n为3倍数时,Fail,否则Win。这也是找规律的常见手段,枚举状态找规律。
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1000+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n;int main()
{while(~scanf("%d",&n)){if(n%3 == 0) printf("Cici\n");else printf("Kiki\n");}return 0;
}/*
n张牌,轮流抓牌,每次抓的牌数是2的幂次,最后抓完牌的胜
*/

HDU2147 —— kiki’s game

题意:推方格,从(n,m)开始推,每次只能往左一格,往下一格,往左下一格,不能推了则为输。(0&lt;n,m≤2000)(0&lt;n,m\leq 2000)(0<n,m≤2000)
思路:博弈问题本质是个游戏,拿到问题的第一步应该是对于小状态进行模拟,很多简单找规律的问题都会迎刃而解。

111表示必胜态,000表示必败态,可以发现000出现的位置是固定的,即行数列数均为奇数的地方,由此此题解决。
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 2000+1;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n,m;int main()
{while(~scanf("%d%d",&n,&m)){if(n == 0 || m == 0) break;if(n%2 && m%2) printf("What a pity!\n");else printf("Wonderful!\n");}return 0;
}/*
推方格,从(n,m)开始推,每次只能往左一格,往下一格,往左下一格,不能推了则为输。
*/

POJ1740 —— A New Stone Game

题意:对于n堆石子,每堆若干个,两人轮流操作,每次操作分两步。① 从某堆中去掉至少一个 ② (可省略) 把该堆剩余石子的一部分分给其它的某些堆。最后谁无子可取即输。
思路:此时可以先考虑只有两堆石子的时候,应该如何判断。不难发现,假如两堆石头一样多,则后者可以完全模仿前者的操作 (“模仿”与“两两分组”是最常见的博弈手段之一),因此我们可以考虑将相同堆数的石头进行两两分组。
不难发现,如果石头堆数为偶数个,且恰好可以两两分组,并且每组中石头个数一致,则一定是必败态。即下图这种情况。

然后我们来证明其他所有情况均可转化为必胜态。假如nnn为奇数,则一定可以利用最多的那堆石子,将其他n−1n-1n−1堆石子进行两两分组。如下图所示,利用A部分使得第一堆与第二堆相同,利用B部分使第三堆和第四堆相同。

如果石子个数为偶数,但是并不能恰好两两分组,则将最大的一堆石子与最小的那堆石子进行匹配,然后利用最大的那堆石子填充其余每组石子之间的差距,构造出一个必败态。
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n,vis[N];int main()
{while(~scanf("%d",&n)){if(!n) break;rep(i,0,100) vis[i] = 0;rep(i,1,n){int xx; scanf("%d",&xx);vis[xx]++;}if(n%2 == 1){printf("1\n");continue;} int jud = 0;rep(i,0,100){if(vis[i]%2 == 1) jud = 1;}if(jud) printf("1\n");else printf("0\n");}return 0;
}/*
对于n堆石子,每堆若干个,两人轮流操作,每次操作分两步.
第一步从某堆中去掉至少一个.
第二步(可省略)把该堆剩余石子的一部分分给其它的某些堆。最后谁无子可取即输。
*/

HDU4388 Stone Game II

题意:nnn堆石子,每堆石子有一定的数目,每次操作任选一堆石子,该堆石子原数目为xxx,取石子至仅剩kkk个,要求k ^ x < x。取完石子后再增加一堆石子,石子个数为k ^ x。每个选手在每轮游戏中仅有一次机会将增加的那一堆石子个数改为2*k^x。问谁能获胜。
思路:这个题的主要难点在于如何处理k ^ x < x的问题,这个限制有什么性质。因此我们需要打表,查看k与k ^ x与x的关系,打表之后可以发现无论如何取,x与k ^ x二进制形式中111的个数与xxx中111的个数奇偶性相同。
假设一堆个数为xxx的石子,二进制中有kkk个111,最后分为了mmm堆,由于最后每一堆石子个数二进制形式中都只有111个111,因此mmm与kkk奇偶性相同。而mmm堆即分了m−1m-1m−1次,所以通过mmm的奇偶性即可判定先手胜负。
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int countt(int x){int num = 0;while(x){if(x&1) num++; x >>= 1;}return num;
}int main()
{int _,n,tp; scanf("%d",&_);rep(kk,1,_){scanf("%d",&n); tp = 0;rep(i,1,n){int xx; scanf("%d",&xx);tp += countt(xx)-1;}printf("Case %d: ",kk);if(tp%2) printf("Yes\n");else printf("No\n");}
}/* 打表程序
int main()
{int n = 100;rep(i,1,n){printf("************\n");LOG2("i",i,"num",countt(i));rep(j,1,i-1){if((j^i) < i){LOG3("j",j,"j^i",(j^i),"num",(countt(j)+countt(j^i)));}}}return 0;
}*/

总结:

找规律问题经常在博弈问题中出现,不属于特定的模型,但是需要找到规律。而找规律通常的方法有 ① 小状态枚举 ② 打表找规律 ③ 奇偶讨论、两两分组、模仿先手行为等策略。

【博弈找规律问题汇总】相关推荐

  1. HDU-1847 Good Luck in CET-4 Everybody! (博弈+找规律)

    大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载的当代大学生,Kiki和Cici更懂得考 ...

  2. CodeForces - 603C Lieges of Legendre(博弈+找规律)

    题目链接:点击查看 题目大意:首先给出n堆石子和一个k值,两人轮流按照规则操作,不能操作的一方即为失败,每一次都有两种操作: 从任意一堆石子中取走一个石子 任选一堆偶数个的石子,将其转换成k堆x/2的 ...

  3. 思维、找规律题目汇总

    转自:http://hi.baidu.com/liuzhe/blog/item/d2dc0fd10bf1eadb572c843d.html 感想: 1.还是数学有前途 2.猜想很重要 3.暴力打表可以 ...

  4. hdu5963 朋友(博弈找规律)

    思路:先考虑是一条链的情况,每次操作一个节点,原本1的变0,0的变1,比较容易猜到的就是与根节点连边的奇偶性相关,然后树或者森林其实也是同理的.. #include<bits/stdc++.h& ...

  5. HDU 2897 (博弈 找规律) 邂逅明下

    根据博弈论的两条规则: 一个状态是必胜状态当且仅当有一个后继是必败状态 一个状态是必败状态当且仅当所有后继都是必胜状态 然后很容易发现从1开始,前p个状态是必败状态,后面q个状态是必胜状态,然后循环往 ...

  6. HDU 1847 (博弈 找规律) Good Luck in CET-4 Everybody!

    为了提高题解质量还是简单证明一下:3的倍数是必败状态. 如果n % 3 = 1,那么拿走1个石子:如果n % 3 = 2,那么拿走两个石子,都将转移到3的倍数的状态.所以每个必胜状态都有一个后继是必败 ...

  7. NEUQOJ 题目1490 田鼠 pk 船长(博弈找规律)

    1490: 田鼠 pk 船长 时间限制: 1 Sec   内存限制: 128 MB 提交: 74   解决: 14 [ 提交][ 状态][ 讨论版] 题目描述 船长和田鼠最近在玩一个取石子的游戏,石子 ...

  8. 笔试逻辑智力题数列找规律小结

    1.  找增幅 1)增幅相等   增幅相等时,为递增或递减的等差数列.   例如:0,3,6,9,12-    2)增幅不相等   a.增幅不完全相等.看是否为等差数列和等差数列互相交叉,或者等差和等 ...

  9. 点分治问题 ----------- P3727 曼哈顿计划E[点分治+博弈SG函数打表找规律]

    题目链接 解题思路: 1.首先对于每个操作我们实际上是一个博弈问题 对于k=1的操作就是很基础的NIM游戏就是找到一条链的异或和为0 对于k=2的操作通过达打表找规律: 如果s是奇数那么偶数的SG函数 ...

  10. 【HDU - 5963】朋友(博弈,思维,必胜态必败态,找规律)

    题干: B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始, ...

最新文章

  1. Oracle数据库之PL/SQL程序基础设计
  2. 使用blas做矩阵乘法
  3. 程序员再也不担心请不到假了!
  4. 【TensorFlow】TensorFlow函数精讲之tf.train.exponential_decay()
  5. np.mean(data, axis=0)函数
  6. 前端 new实例后销毁实例_后浇带怎么做不漏浆?看个实例
  7. 艰难时局下电子发现蓬勃发展
  8. Mina(1):快速上手
  9. 鸟哥linux基础篇学完到什么程度,学完了《鸟哥Linux私房菜》大体回顾以及感悟。...
  10. Phase2 Day16 数据库SQL
  11. Axure动态显示实时时间
  12. 萌新的linux之旅27
  13. 面试官问:为什么 Java 线程没有Running状态?我懵了
  14. VUE进阶篇Part9(render函数)
  15. linux服务器校对和手动修改时间
  16. vb.net 教程 序
  17. 个性化推荐技术的十大挑战
  18. PhotoZoom控制面板简介说明
  19. java五子棋难度设置_tiger(我) 用 java写简易五子棋游戏 上次没通过这次看看行不行...
  20. 哈尔滨工业大学计算机系统大作业——程序人生-Hello’s P2P

热门文章

  1. GDI+中发生一般性错误的解决办法(转)
  2. P2P概览与原理解析
  3. VMware Converter Standalone结合TrueImage 迁移HyperV虚机
  4. python dataframe行数_python – 如何在DataFrame中增加groupby中的行数
  5. Linux学习笔记4 - Linux常用命令
  6. 坚果云 linux 脚本,深度操作系统Deepin安装坚果云
  7. 计算机应用基础课程基本要求,《计算机应用基础》课程建设规范
  8. qq 音乐 python 登录_手把手教你使用Python抓取QQ音乐数据(第四弹)
  9. python已知y求x_Python刷题:集合S(k)求|x-y|最小时的x和y(位运算)
  10. java多窗口,主编处理java代码怎么实现多个窗口