CSU 2115 Multiplication Game (素数筛法)

题意

Alice和Bob玩游戏。
给定一个数N。初始M=1。每轮操作要求从N的素因子中选一个数p出来,然后M=M*p。最后一轮使得M=N的人获胜。M大于N,平局。

解题

因为1e12差不多接近了2^31,所以先对[1,1e6]的范围打一个素数表。
根据这个素数表,对N进行质因数分解。
分解后的结果有三种情况:
(1)有三个及以上的质因子。这时肯定打平。
(2)有两个质因子。这时看这两个质因子出现的次数,分别设为x和y。如果x=y,先手输。x-y=1,先手赢。x-y>1,平局。
(3)一个质因子。奇数个则先手赢,否则先手输。

AC代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;
const int maxn=1e6+7;
int ans[maxn+1],tot;
bool valid[maxn+1];
int a[maxn+1],b[maxn+1];

void getPrime(int n)
{
    memset(valid,true,sizeof(valid));
    for(int i=2;i<=n;i++)
    {
        if(valid[i])
        {
            tot++;
            ans[tot]=i;
        }
        for(int j=1;j<=tot && i*ans[j]<=n;j++)
        {
            valid[i*ans[j]]=false;
            if(i%ans[j]==0) break;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    char name[20];
    tot=0;
    getPrime(maxn);
    while(T--)
    {
        int x;
        int cnt=0;
        scanf("%d %s",&x,name);
        for(int i=1; i<=tot; i++)
        {
            if(x%ans[i]==0)
            {
                a[++cnt]=ans[i];
                b[cnt]=0;
                if(cnt>=3)
                {
                    break;
                }
                while(x%ans[i]==0)
                {
                    ++b[cnt];
                    x/=ans[i];
                }
            }
        }
        if(x!=1)
        {
            a[++cnt]=x;
            b[cnt]=1;
        }
        if(cnt>=3) printf("tie\n");
        else if(cnt==1)
        {
            if(b[cnt]&1) printf("%s\n",name[0]=='A'?"Alice":"Bob");
            else printf("%s\n",name[0]=='A'?"Bob":"Alice");
        }
        else
        {
            if(abs(b[1]-b[2])>1) printf("tie\n");
            else if(abs(b[1]-b[2])==1) printf("%s\n",name[0]=='A'?"Alice":"Bob");
            else printf("%s\n",name[0]=='A'?"Bob":"Alice");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37685156/article/details/81274677