欧几里德游戏
来源:互联网 发布:中国电信cn2网络 编辑:程序博客网 时间:2024/05/01 09:30
一 欧几里德游戏描述:
一开始,板上写有两个不相等的正整数。两个玩家交替写数字,每一次,当前玩家都必须在板上写出任意两个板上数字的差,而且这个数字必须是新的,也就是说,不能与板上任何一个已有的数字相同。当玩家再也写不出新数字时,他就输了。请问,你是选择先行动还是后行动呢?
二 该问题分析过程
注意该题分析时,板上的数字不考虑0和负数。
举例说明:
观察板上的全部数字是 1,2,3,4,5,6,7;共7个数字
观察板上的全部数字是3,6,9 ;共3个数字
观察板上的全部数字是2,4,6,8 ;共4个数字
4)假设一开始板上有的数字为24和60,那么能够写出的序列是36,12,48(序列是任意的),因此应该是先行动。
观察板上的全部数字是12,24,36,48,60共5个;
观察可得出,板上写出来的数字都是一开始那两个数字m,n的最大公约数 r 的倍数。其实,实质就是与欧几里德算法求最大公约数有关。
欧几里德算法 (求最大公约数),就是我们常说的辗转相除。除法是与减法相对应的运算,所以我们将两个不相等的正整数辗转相减,得到的最小值一定是这两个数的最大公约数。(如果你实在不能理解,就先去弄懂辗转相除求最大公因数的实质)。
因此,由以上分析可得,板上的数字一定都是r 的倍数,且一定小于m,n中较大的数。所以,我们选择 m ,n 中的较大数,然后除以r 就可得出板上的全部数字的个数。若数字为偶数,则后行动;若该数字为奇数,则先行动。
三 实现代码
#include<iostream>
using namespace std;
#include<cmath>
int gcd(int m,int n) //求最大公约数
{
int r;
while(n)
{
r=m%n;
m=n;
n=r;
}
return m;
}
int EuclidGame(int m,int n)
{
int r;
if(m<=0||n<=0||m==n) //检测输入 两个不相等的正整数
return -1;
r=gcd(m,n);
if(m>n)
return (m/r)%2;
else
return (n/r)%2;
}
int main()
{
int m,n;
int result;
cout<<"请输入两个不相等的正整数:"<<endl;
cin>>m>>n;
result=EuclidGame(m,n);
if (result==-1)
cout<<"输入错误!注意:应该输入两个不相等的正整数。"<<endl;
else if(result)
cout<<"先行动会赢!"<<endl;
else
cout<<"后行动会赢!"<<endl;
}
四 参考
1 blog.sina.com.cn/s/blog_7496d1d60100t7qe.html
2 Anany Levitin 《算法设计与分析基础》(第2版)
- 欧几里德游戏
- 1781 欧几里德游戏
- 【VIJOS】1208 欧几里德游戏
- 欧几里德的游戏
- 欧几里德的游戏
- [P1290]欧几里德的游戏
- 洛谷1290 欧几里德的游戏
- 洛谷 P1290 欧几里德的游戏
- 洛谷 P1290 欧几里德的游戏
- 欧几里德游戏(归纳总结)
- 洛谷 P1290 欧几里德的游戏 黄金分割
- 【洛谷 1290】 欧几里德的游戏 博弈论
- 数学-洛谷P1290 欧几里德的游戏
- 【博弈论】洛谷 P1290 欧几里德的游戏
- 欧几里德
- 洛谷 P1290 欧几里德的游戏(数论,数学)
- 欧几里德和扩展欧几里德
- 欧几里德, 与 扩展欧几里德
- linux0.11学习笔记(2)
- 1的个数
- [leetcode] Maximum Product Subarray
- 二叉树前序遍历的非递归实现(京东笔试考过)
- java获取中国城市代码 中国城市ID(天气预报可用哦)
- 欧几里德游戏
- poj 2513 Colored Sticks(欧拉通路+并查集+字典树)
- spark调优经验(待续)
- android图片导致bin文件夹和apk很大
- hdu 4465 求期望
- 【AC自动机】 BZOJ 2434 [Noi2011]阿狸的打字机
- 澳哑兆缓酉硕毒司疟第
- 2015互联网校招总结—一路走来
- helloworld!