Multiplication Game

时间限制: 5 Sec   内存限制: 128 MB
提交: 241   解决: 57
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

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?

输入

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≤231-1) followed by the name of the player making  the first turn. The name is either Alice or Bob.

输出

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

样例输入

10
10 Alice
20 Bob
30 Alice
40 Bob

50 Alice

60 Bob

70 Alice

80 Bob

90 Alice

100 Bob

样例输出

Bob

Bob

tie

tie

Alice

tie

tie

tie

tie

Alice

题意:给定一个整数n,选择n的素质数(素数且是n的质数)p,m=1,m*=p,谁先使得m==n,谁就获胜,当m>n时,为平局。

分析:设n的素质数种类为sum;当sum>=3时,为平局;当sum=1时,素质数的个数为偶数第二个获胜,为奇数第一个获胜;当sum=2时,两种素质数的个数相差大于1时为平局,等于1时第一个获胜,小于1时第二个获胜。



#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<iostream>
#include<map>
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,m,n) for(i=m;i<=n;i++)
typedef long long ll;
using namespace std;
int max3(int a,int b,int c){return max(max(a,b),c);}
ll min3(ll a,ll b,ll c){return min(min(a,b),c);}
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll Fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n;n=n*n;}return r;}
int a[100000]={0},x[100000];//数组一定要够大
int cnt;
void sushu()//素数表
{
    int i,j,k;
    k=0;
    for(i=2;i<100000;i++)
    {
        int flag=0;
        for(j=2;j<=sqrt(i);j++)
        {
            if(i%j==0)
            {
                flag=1;
                break;
            }
        }
        if(!flag)
        {
            a[k++]=i;
        }
    }
    cnt=k;//素数的个数
}
int main()
{
	ll t;
	scanf("%lld",&t);
	sushu();
	while(t--)
        {
        ll n;
        char s[10];
        scanf("%lld",&n);
        scanf("%s",s);
        ll sum=0;
        ll vis[1000]={0};//记录每种素质数的个数
        ll tmp=n;
        int flag=0;
        for(int i=0;a[i]*a[i]<=tmp&&i<cnt;i++)//找素质数
        {
            if(tmp%a[i]==0)
            {
                sum++;
                if(sum>2)
                {
                    flag=1;
                    break;
                }
                while(tmp%a[i]==0)
                {
                    tmp/=a[i];
                    vis[sum]++;//素质数的个数
                }
            }
        }
        if(flag)
        {
            printf("tie\n");
            continue;
        }
        if(tmp!=1)
        {
            sum++;
            vis[sum]++;
        }
        if(sum==1)
        {
            if(vis[1]%2==0)
                printf("%s\n",s[0]=='A'?"Bob":"Alice");
            else
                printf("%s\n",s);
        }
        else if(sum==2)
        {
            if(fabs(vis[1]-vis[2])>1)
                printf("tie\n");
            else
            {
                if(fabs(vis[1]-vis[2])==0)
                {
                    printf("%s\n",s[0]=='A'?"Bob":"Alice");
                }
                else
                    printf("%s\n",s);
            }
        }
        else
        {
            printf("tie\n");
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值