C - Multiplication Game (博弈)

Alice and Bob are in their class doing drills on multiplication and division. They quickly get bored and instead decide to play a game they invented.

The game starts with a target integer $ N ≥ 2$ , and an integer $ M = 1 $. Alice and Bob take alternate turns. At each turn, the player chooses a prime divisor p of N, and multiply M by p. If the player’s move makes the value of M equal to the target N, the player wins. If $ M > N $ , the game is a tie. Assuming that both players play optimally, who (if any) is going to win?

Input

The first line of input contains $ T (1 ≤ T ≤ 10000) $ , the number of cases to follow. Each of the next T lines describe a case. Each case is specified by $ N (2 ≤ N ≤ 2^{31} − 1) $ followed by the name of the player making the first turn. The name is either Alice or Bob.

Output

For each case, print the name of the winner (Alice or Bob) assuming optimal play, or tie if there is no winner.

Sample Input

10
10 Alice
20 Bob
30 Alice
40 Bob
50 Alice
60 Bob
70 Alice
80 Bob
90 Alice
100 Bob

Sample Output

Bob
Bob
tie
tie
Alice
tie
tie
tie
tie
Alice

假设N的素因子种类数为num。

当num=1,a[0]%2==0则输,否则赢。

当num=2,abs(a[0]-a[1])=1则赢,a[0]==a[1]则输,其他情况平局。

当num>=3,都是平局。(做这道题的时候,思维局限了,需要从博弈论的角度去考虑,多谢学长赛后耐心的指导)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<algorithm>
using namespace std;
int a[3];
char s[5];
int prim[1000005],m,n,vis[1000005];
void prime()
{
    m=0;
    memset(vis,0,sizeof(vis));
    for(int i=2;i*i<=500000;i++)
    {
        if(!vis[i])
        {
            for(int j=i*i;j<=500000;j+=i) vis[j]=1;
        }
    }
    for(int i=2;i<500000;i++) if(!vis[i]) prim[m++]=i;
}
int main()
{
    int t;
    prime();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%s",&n,&s);
        int num=0;
        memset(a,0,sizeof(a));
        for(int j=0;j<m;j++)
        {
            int i=prim[j];
            if(n<=1) break;
            if(n%i==0&&n)
            {
                int cnt=0;
                while(n%i==0)
                    n/=i,cnt++;
                a[num]=cnt;
                num++;
                if(num>=3) break;
            }
        }
        if(n>1) a[num++]++;
        if(num==1)
        {
            if(a[0]%2==0)
            {
                if(s[0]=='A') printf("Bob\n");
                else printf("Alice\n");
            }
            else printf("%s\n",s);
        }
        else if(num>=3) printf("tie\n");
        else
        {
            if(a[0]==a[1])
            {
                if(s[0]=='A') printf("Bob\n");
                else printf("Alice\n");
            }
            else if(abs(a[0]-a[1])==1) printf("%s\n",s);
            else printf("tie\n");
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值