OpenJudge计算概论-取石子游戏

简介: OpenJudge计算概论-取石子游戏【函数递归练习】 /*====================================================================== 取石子游戏 总时间限制:  1000ms       内存限制: 65536kB 描述 有两堆石子,两个人轮流去取.

OpenJudge计算概论-取石子游戏【函数递归练习】

/*======================================================================

取石子游戏

总时间限制:  1000ms       内存限制: 65536kB

描述

有两堆石子,两个人轮流去取.每次取的时候,只能从较多的那堆石子里取,并且取的数目必须是较少的那堆石子数目的整数倍.最后谁能够把一堆石子取空谁就算赢. 
比如初始的时候两堆石子的数目是25和7 

25 7

-->

11 7

-->

4 7

-->

4 3

-->

1 3

-->

1 0

 

选手1取

 

选手2取

 

选手1取

 

选手2取

 

选手1取

 

最后选手1(先取的)获胜,在取的过程中选手2都只有唯一的一种取法。 
给定初始时石子的数目,如果两个人都采取最优策略,请问先手能否获胜。

输入

输入包含多数数据。每组数据一行,包含两个正整数a和b,表示初始时石子的数目。
输入以两个0表示结束。

输出

如果先手胜,输出"win",否则输出"lose"

样例输入

34 12

15 24

0 0

样例输出

win

lose

提示

假设石子数目为(a,b)且a >= b,如果[a/b] >= 2则先手必胜,如果[a/b]<2,那么先手只有唯一的一种取法.
[a/b]表示a除以b取整后的值.

========================================================================*/

解析:(《数学与程序设计》东南大学出版社page5例题1-2 欧几里德的游戏)

这道题会使人想到辗转相除法。其实,辗转相除法的除数和余数所形成的各种状态都会在游戏过程中出现。例如下面的游戏过程:

游戏过程的各个状态

辗转相除法的过程

属于哪一局

所属情况

50  18

50/18=2……14

第1局初状态

第一种

32  18

 

第1局末状态

14  18

18/14=1……4

第2局初状态

(也是末状态)

第二种

14  4

14/4=3……2

第3局初始状态

第一种

10  4

 

第3局中间状态

6  4

 

第3局末状态

2  4

4/2=2……0

第4局

 

我们可以把一步辗转相除以及它与下一步辗转相除法之间的游戏状态称作一局,辗转相除的被除数和除数实际上对应了每一局的初状态。显然,每一局的初状态是游戏中必然出现的,而且最后一局只有一个状态,面临最后一局初状态的人就赢得了胜利。

因此,本题对的大致想法是:尽量让自己能取得每一局的初状态,让对手取得每一局(除最后一局)的末状态。下面分两种情况来具体说说这个想法的实现:

第一种情况:先举一个例子A=32,B=14,A和B的辗转相除法过程如下:

32/14=2……4

14/4=3……2

4/2=2……0

这种情况的特点是:每一步相除所得的商都大于1,即对于每一局的初状态(A,B),A>B,都满足:A/B>1。对这种情况,我们的策略是取走(A/B-1)*B,这样就得到新状态(A  mod  B+B,B),接下来,对手就没有选择,只能取走B,剩下(A  mod  B,B),而这就是下一句的初状态,这样就保证下一局的初状态肯定由自己取,这种情况下先取者必胜。

第二种情况:某一局的初状态满足A/B=1,即这一局只有一个状态,自己取完之后下一局的初状态必然落在对方手里。以下是这种情况的一般性表述:存在连续的若干局Pi(Ai,Bi),……Pj(Aj,Bj),i+1<j,Ai/Bi>1,且对于任意一局Pk(Ak,Bk),i<k<j,均满足Ak/Bk=1。如果j-i是奇数,则Pj和Pi的初始状态的持有人是相同的,如果j-i是偶数则不同。因此,如果出现j-i为偶数,就有必要在Pi局中把当局的状态一次性全部取完,即把下一局的初状态拱手相让,这样就保证在Pj局中再次拿到初状态。

总之,首先拿到A/B>1状态的人,总能根据两种情况作出正确的选择,从而在最后一局拿到初状态。因此,首先拿到A/B>1状态的人是必胜的,但如果出现从初状态开始,每局都是A/B=1,如A=24,B=15,则要根据这样的局数多少来判断输赢。

解决代码如下:

#include<stdio.h>
int main()
{
    int a,b;
    int t,f,c;
    scanf("%d%d",&a,&b);
    while(a!=0&&b!=0)
    {
        if(a<b)
        {
            t=a;a=b;b=t;
        }
        f=1;//1表示选手赢,-1表示选手1输。
        while((c=a/b)==1&&(a%b!=0))
        {
            t=a%b;
            a=b;
            b=t;
            f=-f;
        }
        if(f==1)  printf("win\n");
        else printf("lose\n");
        scanf("%d%d",&a,&b);
    }
    return 0;
}

其实也可以用递归来做,但其实递归没有上面这个这么好理解:

#include<stdio.h>
int f;
int fun(int a,int b);
int main()
{
    int a,b;
    int t,c;
    scanf("%d%d",&a,&b);
    while(a!=0&&b!=0)
    {
        if(a<b)
        {
            t=a;a=b;b=t;
        }
        f=1;//1表示选手赢,-1表示选手1输。
        f=fun(a,b);
        if(f==1)  printf("win\n");
        else printf("lose\n");
        scanf("%d%d",&a,&b);
    }
    return 0;
}
int fun(int a,int b)
{
    int c;
    if((c=a/b)>1||(a%b==0))
        return f;
    else
    {
        f=-f;
    }    return fun(b,a%b);
}

 

 

相关文章
|
JSON JavaScript 搜索推荐
Github 精选 #4 | 让 Github 帮你自动压缩图片!
Github 精选 #4 | 让 Github 帮你自动压缩图片!
Github 精选 #4 | 让 Github 帮你自动压缩图片!
|
9月前
|
Kubernetes Linux Go
使用 Uber automaxprocs 正确设置 Go 程序线程数
`automaxprocs` 包就是专门用来解决此问题的,并且用法非常简单,只需要使用匿名导入的方式 `import _ "go.uber.org/automaxprocs"` 一行代码即可搞定。
416 78
|
存储 JSON 安全
Token验证技术文档
【7月更文挑战第6天】Token验证是现代Web应用中常见的安全措施,用于确保用户身份的合法性和请求的安全性。它基于令牌(Token)的概念,通过在客户端和服务端之间传递一个安全的、有时限的字符串来验证用户身份,替代传统的基于会话的认证机制。本文档旨在介绍一种基本的Token验证流程,并提供一个简单的代码示例,使用JSON Web Tokens (JWT) 实现这一过程。
1808 1
An动画基础之元件的影片剪辑效果
An动画基础之元件的影片剪辑效果
1035 0
An动画基础之元件的影片剪辑效果
|
Linux 网络安全 调度
DolphinScheduler 调度工作流报错 Host key verification failed.
DolphinScheduler调度任务失败,错误显示&quot;Host key verification failed.&quot;。问题可能在于SSH免密登录配置失效或租户不存在于Linux系统中。解决方案:检查SSH配置并确保调度用户有管理员权限;确认DolphinScheduler租户与Linux用户对应。如果日志仅显示主机键验证失败,可能忽略了租户与操作系统用户的对应关系。创建具备管理员权限的新租户可解决。此外,当失败策略设为&quot;继续&quot;时,可能无法查看失败日志,建议使用&quot;结束&quot;策略。
513 0
|
项目管理
深入解析PMP组织资产
在项目管理领域,PMP(项目管理专业人士)认证是一项备受尊敬的资格证书,它不仅代表了专业知识和技能,还强调了对组织资产的充分了解和合理运用。本文将深入探讨PMP组织资产的重要性以及如何详细解析它们,以提高项目管理的效率和成功率。
|
新零售 运维 供应链
解决方案应用实例 |阿里云牵手飞鹤乳业,全面赋能企业数字化升级
宏观经济环境变化、新一代消费者崛起,飞鹤借助阿里云数智化转型,以数字化、智能化引领企业业务革新以及灵活多变的业务模式,拥抱迅速变化的市场环境、服务年轻消费群体。
2882 2
解决方案应用实例 |阿里云牵手飞鹤乳业,全面赋能企业数字化升级
|
Prometheus 资源调度 监控
Prometheus PushGateway 碎碎念
Prometheus 是一套开源的监控告警系统,PushGateway 是其中一个组件。这个组件用来收取推送来的数据并且供 Prometheus 来拉取。
590 0
|
存储 小程序 数据库
手把手教学,从零到一打造一款专属的情侣小程序
很久之前就想做个情侣小程序来记录我们之间的一些事情,偶然翻开一年前自己制作的一个小程序(未完成版),虽然代码下的有点乱,但感觉可以重构一下,在此给大家展示一下,也希望在设计和功能上,大家可以给点意见,后续有空再进行完善。
1603 0
手把手教学,从零到一打造一款专属的情侣小程序

热门文章

最新文章