A game题解(博弈论)

文章讲述了Tony和Macle在生日派对上玩的一个决定谁与公主共进晚餐的游戏。规则是将木棍分成等长段,不能少于k。当木棍数量为偶数时,Tony必败;奇数时,Macle只要能找到能整除k的分割次数就能获胜。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目网址:Problem - 1543 (nefu.edu.cn)
Tony and Macle are good friends. One day they joined a birthday party together. Fortunately,
they got the opportunity to have dinner with the princess, but only one person had the chance. So
they decided to play a game to decide who could have dinner with the princess.
The rules of the game are very simple. At first, there are n sticks. Each of exactly m meters in
length. Each person takes turns. For one move the player chooses just one stick and cut it into
several equal length sticks, and the length of each stick is an integer and no less than k. Each
resulting part is also a stick which can be chosen in the future. The player who can't make a move
loses the game ,thus the other one win.
Macle make the first move.

Input

the first line contains tree integer n,m,k(1 <= n,m,k <= 10^9).

Output

print 'Macle' if Macle wins or 'Tony' if Tony wins,you should print everything without quotes.

Sample Input

1 15 4

Sample Output

Macle

Hint

第2组:
4 9 5
Tony

思路:

由于每根木棍都相等,所以sg(m)都一样,所以当n为偶数时,n个值异或为o,Macle必败。

当n为奇数时,只剩一个sg(m),用了sg模板会超时,只能手动分析了。

n为奇数时的答案和n=1时答案一样,我们只分析一根木棍,对于一根木棍,只要他能分段,他就一定能一次分到不能再分的段数,所以枚举段数(2,m/k),只要找到一个可以分得段数,Macle赢。

注意:可能是数据问题,枚举段数从大到小枚举,从小到大会超时。

代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<unordered_map>
#include<map>
using namespace std;
#define LL long long
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
const int N = 1e5 + 100;
LL k, n, m;
LL ans = 0;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m >> k;
    if (n % 2 == 0)
        cout << "Tony" << endl;
    else
    {
        int flag = 0;
        int y = m / k;
        for (int i = y; i >= 2; i--)
            if (m % i == 0)
            {
                flag = 1;
                break;
            }
        if (flag)
            cout << "Macle" << endl;
        else
            cout << "Tony" << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值