Euclid`s Game
题目
给定两个整数 a 和 b,Stan和Ollie轮流从较大的数字中减去较小的数的倍数。这里的倍数是指1倍、2倍这样的整数倍,并且相减后的结果不能小于0。Stan先手,在自己的回合将其中一个数变成零的一方获胜。当双方都采取最优策略时,谁会获胜?
分析
不妨设 a<b,
情况一:若b<2a,则(a, b)只能变成(a, b-a);一旦出现 b%a==0,则先手赢。
情况二:若b>2a,则(a, b)可变成(a, b%a+a),回到了第一种情况。先手每次都能变回情况一,后手每次只能b-a,总会出现a|b,先手就能赢。也就是说这种情况先手必赢。
//还是可以套用打表模板,只是需要加上两条必胜情况的判断,不然时间复杂度太高
//在先手不能必赢的情况下,如果后手sg值不全为0,先手还能平局;如果后手sg值全为0,先手必败
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std; typedef long long ll;
typedef pair<ll, ll> P;
const int maxn = ;
map<P, int>mp; int dfs(ll a, ll b) //必胜返回1,平局返回2,必败返回-1
{
//printf("%lld %lld\n, a, b);
if(a < b) swap(a, b);
int& ret = mp[make_pair(a, b)];
if(ret) return ret;
if(a == || b == ) return ret=-;
if(a % b == ) return ret=; //
if(a - b > b) return ret=; //加了两条必胜判断
bool flag = false; //能否成平局
for(ll i = ;b*i <= a;i++)
{
int tmp = dfs(a-b*i, b);
if(tmp == -) return ret=; //后面存在必败态,先手必胜
if(tmp == ) flag = true; //存在平局 }
return ret=(flag ? : -);
} int main()
{ ll a, b;
while(scanf("%lld%lld", &a, &b) == && a)
{
if(dfs(a, b) == ) printf("Stan wins\n");
else printf("Ollie wins\n");
}
return ;
}
简化版:
#include<bits/stdc++.h>
using namespace std; int a, b; void solve()
{
bool flag = true;
while(true)
{
if(a > b) swap(a, b);
if(b % a == ) break;
if(b -a > a) break; //情况二
b -= a; //情况一
flag = !flag;
}
if(flag) printf("Stan wins\n");
else printf("Ollie wins\n");
} int main()
{
while(scanf("%d%d", &a, &b) == && a)
{
solve();
} return ;
}
Euclid`s Game的更多相关文章
- ZOJ1913 Euclid's Game (第一道简单的博弈题)
题目描述: Euclid's Game Time Limit: 2 Seconds Memory Limit: 65536 KB Two players, Stan and Ollie, p ...
- Euclid求最大公约数
Euclid求最大公约数算法 #include <stdio.h> int gcd(int x,int y){ while(x!=y){ if(x>y) x=x-y; else y= ...
- HDU 1525 Euclid's Game 博弈
Euclid's Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- [poj2348]Euclid's Game(博弈论+gcd)
Euclid's Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9033 Accepted: 3695 Des ...
- hdu------(1525)Euclid's Game(博弈决策树)
Euclid's Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- HDU 1525 Euclid's Game (博弈)
Euclid's Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 最大公约数与欧几里得(Euclid)算法
---恢复内容开始--- 记a, b的最大公约数为gcd(a, b).显然, gcd(a,b)=gcd(|a|,|b|). 计算最大公约数的Euclid算法基于下面定理: [GCD递归定理]对于任意非 ...
- 求两个数的最大公约数(Euclid算法)
求两个数 p 和 q 的最大公约数(greatest common divisor,gcd),利用性质 如果 p > q, p 和 q 的最大公约数 = q 和 (p % q)的最大公约数. 证 ...
- 最大公约数(gcd):Euclid算法证明
1个常识: 如果 a≥b 并且 b≤a,那么 a=b. 2个前提: 1)只在非负整数范围内讨论两个数 m 和 n 的最大公约数,即 m, n ∈ N. 2)0可以被任何数整除,但是0不能整除任何数,即 ...
- Euclid gcd规则的证明
Euclid 规则:如果x和y都是正整数,而且x>=y,那么gcd(x,y)=gcd(x mod y, y) 假设x和y的gcd为a,那么必然有 x=a*n1 y=a*n2(gcd(n1,n2) ...
随机推荐
- Python3 CGI编程实现教程
一.背景说明 虽然很久以前就听说“早期的网站很多通过cgi形式实现”.“C++可通过CGI形式编写网页”,日积月累对CGI也有了一些概念,但一直没真正见过一个实际运行的CGI网站,总归还是有些底气不足 ...
- 不同路径II --动态规划
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 现在考虑网 ...
- Github Markdown 图片如何并排显示
Github Markdown 图片如何并排显示 要一张图片接着一张图片的写,中间不能有换行.如果换行的话则图片也换行 正确的写法: 
异常清空如图 原因:.net core提交的表单限制太小导致页面表单提交失败 在控制器上使用 RequestFormLimits attribute [RequestFormLimits(ValueC ...
- C# 使用SuperSocket
一.需求场景 (1)使用SuperSocket进行网络通信 二.所需软件 (1)SocketTool 三.实现步骤 (1)使用Nuget管理器安装SuperSocket.Engine 该插件已经包 ...
- linux基础命令汇总
目录 linux系统结构 常用命令 切换目录命令cd 文件操作 vi和vim编辑器 重定向输出>和>> 管道 | &&命令执行控制 网络通讯命令 系统管理命令 用户和 ...
- spark内存管理器--MemoryManager源码解析
MemoryManager内存管理器 内存管理器可以说是spark内核中最重要的基础模块之一,shuffle时的排序,rdd缓存,展开内存,广播变量,Task运行结果的存储等等,凡是需要使用内存的地方 ...