题意:有两堆个数分别为a和b的石子,两个人轮流取石子,一次可以取一堆中任意个数的石子,或者在两堆中取相同个数的石子,最先没有石子可以取的人输,你先取,赢为1输为0。

解法:威佐夫博弈。看完题先找规律,能推理出前几个必败态有1 2, 3 5, 4 7, 6 10……从必败态可以一步达到的状态一定是必胜态,所以在找规律中发现,在必败态的a或b上加若干数,或a和b同时加若干数,就会转化为必胜态,所以下一个必败态不可能会有一个数量和之前的必败态相同,所以下一个必败态的a就是在之前的必败态内没出现过的第一个整数,而对于必败态a和b同时加若干数就转化为必胜态的情况,前一个必败态的a和b的差设为k,那么下一个必败态的差为k + 1时就不会转化为必胜态了,所以得出an和bn的求法,但这题的数据范围太大,不能将所有必败态求出,在这里用到了贝亚蒂定理:

在数论中,贝亚蒂定理(英文:Beatty sequence)指:若使得。定义集(贝亚蒂列,则P 和 Q 构成正整数集的一个分划:

即是说:若两个正无理数倒数之和是1,则任何正整数都可刚好以一种形式表示为不大于其中一个无理数的正整数倍的最大整数。

此定理由Sam Beatty在1926年发现。

——维基百科

通过之前的描述,数列an和bn符合贝亚蒂数列,即两者没有交集,且并集为正整数集。

由贝亚蒂定理可知,an = [np], bn = [nq], 且bn = an + n, 所以bn = np + n = n(p + 1),即q = p + 1,解方程1 / p + 1 / (p + 1) = 1得p = (1 + sqrt(5)) / 2。

所以当给出a和b(a < b)时, n = b - a,若(1 + sqrt(5)) / 2 × n等于a,则说明为必败态。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
int main()
{
int a, b;
while(~scanf("%d%d", &a, &b))
{
if(a > b)
{
int tmp = a;
a = b;
b = tmp;
}
int n = b - a;
if((int)((1 + sqrt(5.0)) * 0.5 * n) == a)
{
puts("0");
}
else
puts("1");
}
return 0;
}

  

POJ 1067 取石子游戏的更多相关文章

  1. POJ.1067 取石子游戏 (博弈论 威佐夫博弈)

    POJ.1067 取石子游戏 (博弈论 威佐夫博弈) 题意分析 简单的威佐夫博弈 博弈论快速入门 代码总览 #include <cstdio> #include <cmath> ...

  2. poj 1067 取石子游戏 (威佐夫博弈)

    取石子游戏 http://poj.org/problem?id=1067 Time Limit: 1000MS   Memory Limit: 10000K       Description 有两堆 ...

  3. poj 1067 取石子游戏( 威佐夫博奕)

    题目:http://poj.org/problem?id=1067 题意:有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的 ...

  4. [原博客] POJ 1067 取石子游戏

    题目链接有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者 ...

  5. Poj 1067 取石子游戏(NIM,威佐夫博奕)

    一.Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子. ...

  6. POJ 1067 取石子游戏 (威佐夫博奕,公式)

    题意: 有两堆石子,两个人轮流取石子.规定每次有两种取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.给定两堆石子数量,问先手的输赢? ...

  7. poj 1067 取石子游戏(威佐夫博奕(Wythoff Game))

    这里不在详细介绍威佐夫博弈论 简单提一下 要先提出一个名词“奇异局势”,如果你面对奇异局势则必输 奇异局势前几项(0,0).(1,2).(3,5).(4,7).(6,10).(8,13).(9,15) ...

  8. POJ 1067 取石子游戏 威佐夫博弈

    威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜. 我们用(ak,bk)(ak ≤ bk ,k= ...

  9. POJ 1067 取石子游戏 [博弈]

    题意:威佐夫博弈. 思路:看了很多证明都没看懂.最后决定就记住结论好了. 对于所有的奇异局面(必败局),有通项公式 Pi = (a, b), (a = i * [(sqrt(5) + 1) / 2], ...

随机推荐

  1. hibernate动态创建数据库表名几种方式

    数据库中数据量很大, 但又不可以删除时同时又要优化程序检索数据时间. 答:方式有很多比如 创建数据库表分区,创建索引, 存储过程等; 我这里采用动态创建数据库表的方式. 完全可以在不创建表分区情况下实 ...

  2. HTTP幂等性

    http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html 理解HTTP幂等性 基于HTTP协议的Web API是时下最为 ...

  3. 服务器程序源代码分析之三:gunicorn

    服务器程序源代码分析之三:gunicorn 时间:2014-05-09 11:33:54 类别:网站架构 访问: 641 次 gunicorn是一个python web 服务部署工具,类似flup,完 ...

  4. C++11 FAQ中文版--转

    更新至英文版October 3, 2012 译者前言: 经过C++标准委员会的不懈努力,最新的ISO C++标准C++11,也即是原来的C++0x,已经正式发布了.让我们欢迎C++11! 今天获得St ...

  5. POJ3297+map字符串处理

    简单的字符串处理题. 要注意细节! 附数据两组: ABCC abc ae AAA abc AAAA abc A a B a C a /* */ #include<stdio.h> #inc ...

  6. linux ubuntu卸载软件

    1.通过deb包安装的情况: 安装.deb包: 代码:sudo dpkg -i package_file.deb反安装.deb包: 代码:sudo dpkg -r package_name 2.通过a ...

  7. codeforces #309 div1 C

    首先我们会发现所有的人构成了一个图 定义相爱为 在一个集合里 定义相恨为 不在一个集合里 很容易发现满足条件的图一定是一个二分图 那么分类讨论如下: 1.如果出现不合法 答案为0 2.如果不是一个二分 ...

  8. [itint5]完全二叉树节点个数的统计

    http://www.itint5.com/oj/#4 这题是利用完全二叉树的性质计算节点数目.那么是通过比较左右子树的最左结点的高度来看那边是满的,然后递归计算. //使用getLeftChildN ...

  9. [topcoder]FlowerGarden

    1.此题很勉强算DP.找了半天网上思路,是个三层的循环,n^3.2.基本思路就是先找到在第一个位置的花.这样就双层遍历,找到所有和其他不冲突的花中最高的一个,然后放到结果的首位.然后去掉此花,继续使用 ...

  10. Fibonacci sequence 求余数

    #include <iostream> using namespace std; int f(int n); int main() { int n; cin>>n; doubl ...