博弈论题目

题目描述

有一个取数的游戏。初始时,给出一个环,环上的每条边上都有一个非负整数。这些整数中至少有一个0。然后,将一枚硬币放在环上的一个节点上。两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流取数,取数的规则如下:

(1)选择硬币左边或者右边的一条边,并且边上的数非0;

(2)将这条边上的数减至任意一个非负整数(至少要有所减小);

(3)将硬币移至边的另一端。

如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了。

如下图,描述的是Alice和Bob两人的对弈过程,其中黑色节点表示硬币所在节点。结果图(d)中,轮到Bob走时,硬币两边的边上都是0,所以Alcie获胜。

(a)Alice (b)Bob (c)Alice (d)Bob

现在,你的任务就是根据给出的环、边上的数值以及起点(硬币所在位置),判断先走方是否有必胜的策略。

输入格式

第一行一个整数N(N≤20),表示环上的节点数。

第二行N个数,数值不超过30,依次表示N条边上的数值。硬币的起始位置在第一条边与最后一条边之间的节点上。

输出格式

仅一行。若存在必胜策略,则输出“YES”,否则输出“NO”。

#include<iostream>
using namespace std;
#define int long long
const int maxn=25;
int a[maxn];
signed main()
{
    int n;cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    int num1=0,num2=0;
    for(int i=n-1;i>=0;i--)
    {
        if(a[i]!=0)
        {
            num1++;
        }
        else break;
    }
    for(int i=0;i<n;i++)
    {
        if(a[i]!=0)
        {
            num2++;
        }
        else
            break;
    }
    if(num1%2==0&&num2%2==0)
    {
        cout<<"NO"<<endl;
    }
    if(num1%2==1||num2%2==1)
    {
        cout<<"YES"<<endl;
    }
    return 0;

题目描述

欧几里德的两个后代 Stan 和 Ollie 正在玩一种数字游戏,这个游戏是他们的祖先欧几里德发明的。给定两个正整数 MM 和 NN,从 Stan 开始,从其中较大的一个数,减去较小的数的正整数倍,当然,得到的数不能小于 00。然后是 Ollie,对刚才得到的数,和 M,NM,N 中较小的那个数,再进行同样的操作……直到一个人得到了 00,他就取得了胜利。下面是他们用 (25,7)(25,7) 两个数游戏的过程:

Start:(25,7)(25,7)

Stan:(11,7)(11,7)

Ollie:(4,7)(4,7)

Stan:(4,3)(4,3)

Ollie:(1,3)(1,3)

Stan:(1,0)(1,0)

Stan 赢得了游戏的胜利。

现在,假设他们完美地操作,谁会取得胜利呢?

输入格式

本题有多组测试数据。

第一行为测试数据的组数 CC。 下面 CC 行,每行为一组数据,包含两个正整数 M,N(M,N<2^{31})M,N(M,N<231)。

输出格式

对每组输入数据输出一行,如果 Stan 胜利,则输出 Stan wins;否则输出 Ollie wins

#include<iostream>
#include<cstdio>
using namespace std;
#define int long long
signed main()
{
    int t;scanf("%lld",&t);
    while(t--)
    {
        int a,b;scanf("%lld%lld",&a,&b);
        if(a==b)
        {
            puts("Stan wins");
            continue;
        }
        if(a<b) swap(a,b);
        int cnt=0;
        while(b)
        {
            if((a/b)>1) break;
            else
            {
                cnt++;
                a%=b;
            }
            swap(a,b);
        }
        if(cnt%2==1) puts("Ollie wins");
        else puts("Stan wins");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值