Problem C. gNumbers Google APAC 2016 University Test Round B

来源:互联网 发布:连衣裙 知乎 编辑:程序博客网 时间:2024/05/29 14:52

看到博弈就懵逼的我><这一题原来是递归做。

如果当前player接手数字N,该方一定赢的条件是存在一种prime factor的选择方法,使得另一方一定会输。

如果当前player接手数字N,该方一定输的条件是没有一种prime factor的选择方法,使得另一方一定会输。i.e., 如果存在一种策略使得另一方一定会输,那么当前player一定不会输。

这样就可以枚举所有的prime factor选择方法,递归处理。

看到N=1e15吓cry了。事实上,前14个质数(2,3,5,7,...so on)相乘就已经超过1e15了,所以N对应的质因子个数不会很多,所以递归层数不会很多。

以及学到了一种神奇的筛质因子的方法。╮(╯▽╰)╭

开始大数据dead了是因为枚举质因子的循环里把long long写成了int。可能因为int溢出变成负数了,循环就出不来了。o(╯□╰)o

#include<iostream>#include<stdio.h>#include<cstdio>#include<string>#include<cmath>#include<stdlib.h>#include<algorithm>#include<string.h>#include<cstring>#include<vector>#include<queue>#include<map>#include<set>using namespace std;//2016 Round B Problem C. gNumbersint T;const int maxn=2010;long long N;bool ans;vector<long long>factors;bool isprime(long long num){    for(long long i=2;i*i<=num;i++)    {        if(i==num) continue;        if(num%i==0)        {            return false;        }    }    return true;}bool isgnumber(long long num){//    if(num==1)//    {//        return true;must return true if num==1//    }    long long sum=0;    while(num>0)    {        sum+=num%10;        num/=10;    }    return isprime(sum);}bool win(long long num);bool lose(long long num)//whether the player handling num must lose, true is mustlose{    //cout<<"lose "<<num<<endl;    if(isgnumber(num)==true)    {        return true;    }    long long tmpnum=num;    for(int i=0;i<factors.size();i++)    {        if(num%factors[i]==0&&isprime(factors[i])==true)//        {            long long tmpnum=num;            while(tmpnum%factors[i]==0)            {                tmpnum/=factors[i];            }            if(win(tmpnum)==false)            {                return false;            }        }    }    return true;}bool win(long long num)//whether the player handling num will win, true is must win{    //cout<<"win "<<num<<endl;    if(isgnumber(num)==true)    {        return false;    }    for(int i=0;i<factors.size();i++)    {        if(num%factors[i]==0&&isprime(factors[i])==true)//tmpnum%factors[i] leads to WA        {            long long tmpnum=num;            while(tmpnum%factors[i]==0)            {                tmpnum/=factors[i];            }            if(lose(tmpnum)==true)            {                return true;            }        }    }    return false;}int main(){//    long long prod=1;//    int cnt=0;//    for(long long i=2;i<45;i++)//    {//        if(isprime(i))//        {//            cnt++;//            prod*=i;//        }//    }//    cout<<cnt<<" "<<prod<<endl;//    return 0;    freopen("C-small-practice.in","r",stdin);//    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d",&T);    for(int ca=1;ca<=T;ca++)    {        factors.clear();        scanf("%lld",&N);        long long tmp=N;        for(long long i=2;i*i<=tmp;i++)//use int i leads to dead loop in large dataset        {            if(tmp%i==0)            {                factors.push_back(i);                while(tmp%i==0)                {                    tmp/=i;                }                //cout<<i<<" "<<tmp<<endl;            }        }        if(tmp>1)        {            factors.push_back(tmp);        }        ans=win(N);        printf("Case #%d: %s\n",ca,(ans==true?"Laurence":"Seymour"));    }    return 0;}


0 0