3696 The Luckiest number 最小X整数倍数 大整数质因数分解及欧拉函数,dfs求大整数的所有约数

The Luckiest number
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2349   Accepted: 537

Description

Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his own lucky number L. Now he wants to construct his luckiest number which is the minimum among all positive integers that are a multiple of L and consist of only digit '8'.

Input

The input consists of multiple test cases. Each test case contains exactly one line containing L(1 ≤ L ≤ 2,000,000,000).

The last test case is followed by a line containing a zero.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the length of Bob's luckiest number. If Bob can't construct his luckiest number, print a zero.

Sample Input

8
11
16
0

Sample Output

Case 1: 1
Case 2: 2
Case 3: 0
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#define bignum long long
using namespace std;
//求a,b的最大公约数
bignum gcd(bignum a,bignum b)
{
    return b==0?a:gcd(b,a%b);
}
//求a*b%c,因为a,b很大,所以要先将b写成二进制数,再加:例如3*7=3*(1+2+4);
bignum mulmod(bignum a,bignum b,bignum c)
{
    bignum cnt=0,temp=a;
    while(b)
    {
        if(b&1) cnt=(cnt+temp)%c;
        temp=(temp+temp)%c;
        b>>=1;
    }
    return cnt;
}
//求a^b%c,再次将b写成二进制形式,例如:3^7=3^1*3^2*3^4;
bignum powmod(bignum a,bignum b,bignum c)
{
    bignum cnt=1,temp=a;
    while(b)
    {
        if(b&1) cnt=mulmod(cnt,temp,c);//cnt=(cnt*temp)%c;
        temp=mulmod(temp,temp,c);//temp=(temp*temp)%c;
        b>>=1;
    }
    return cnt;
}
//Miller-Rabin测试n是否为素数,1表示为素数,0表示非素数
int pri[10]={2,3,5,7,11,13,17,19,23,29};
bool Miller_Rabin(bignum n)
{
    if(n<2) return 0;
    if(n==2) return 1;
    if(!(n&1)) return 0;
    bignum k=0,m;
    m=n-1;
    while(m%2==0) m>>=1,k++;//n-1=m*2^k
    for(int i=0;i<10;i++)
    {
        if(pri[i]>=n) return 1;
        bignum a=powmod(pri[i],m,n);
        if(a==1) continue;
        int j;
        for(j=0;j<k;j++)
        {
            if(a==n-1) break;
            a=mulmod(a,a,n);
        }
        if(j<k) continue;
        return 0;
    }
    return 1;
}
//pollard_rho 大整数分解,给出n的一个非1因子,返回n是为一次没有找到
bignum pollard_rho(bignum C,bignum N)
{
    bignum I, X, Y, K, D;
    I = 1;
    X = rand() % N;
    Y = X;
    K = 2;
    do
    {
        I++;
        D = gcd(N + Y - X, N);
        if (D > 1 && D < N) return D;
        if (I == K) Y = X, K *= 2;
        X = (mulmod(X, X, N) + N - C) % N;
    }while (Y != X);
    return N;
}
//找出N的最小质因数
bignum rho(bignum N)
{
    if (Miller_Rabin(N)) return N;
    do
    {
        bignum T = pollard_rho(rand() % (N - 1) + 1, N);
        if (T < N)
        {
              bignum A, B;
              A = rho(T);
              B = rho(N / T);
              return A < B ? A : B;
        }
    }
    while(1);
}
//N分解质因数,这里是所有质因数,有重复的
bignum AllFac[1100];
int Facnum;
void findrepeatfac(bignum n)
{
    if(Miller_Rabin(n))
    {
        AllFac[++Facnum]=n;
        return ;
    }
    bignum factor;
    do
    {
        factor=pollard_rho(rand() % (n - 1) + 1, n);
    }while(factor>=n);
    findrepeatfac(factor);
    findrepeatfac(n/factor);
}
//求N的所有质因数,是除去重复的
bignum Fac[1100];
int num[1100];
int len;//0-len
void FindFac(bignum n)
{
    len=0;
    //初始化
    memset(AllFac,0,sizeof(AllFac));
    memset(num,0,sizeof(num));
    Facnum=0;
    findrepeatfac(n);
    sort(AllFac+1,AllFac+1+Facnum);
    Fac[0]=AllFac[1];
    num[0]=1;
    for(int i=2;i<=Facnum;i++)
    {
        if(Fac[len]!=AllFac[i])
        {
            Fac[++len]=AllFac[i];//important
        }
        num[len]++;
    }
}
//求n的欧拉函数值
bignum oula(bignum n)
{
    FindFac(n);
    bignum cnt=n;
    for(int i=0;i<=len;i++)
    {
        cnt-=cnt/Fac[i];
    }
    return cnt;
}
//枚举n的所有因子  cnt
/*bignum Fac[1100];
int num[1100];
int len;//0-len
*/
bignum yinzi[100000];
bignum yinzinum;//初始化在main中(0-yinzinum-1)
void dfs(int id,bignum cnt)
{
    yinzi[yinzinum++]=cnt;
    if(id==len+1)
    {
        return ;
    }
    bignum temp=1;
    for(int i=0;i<=num[id];i++)
    {
        dfs(id+1,cnt*temp);
        temp*=Fac[id];
    }
}
int main()
{
    srand(time(NULL));
    bignum l;
    int pl=1;
    while(cin>>l&&l)
    {
        bignum m=9*l/gcd(9*l,8);
        //cout<<"m="<<m<<endl;
        if(gcd(10,m)>1)
        {
            cout<<"Case "<<pl++<<": 0"<<endl;
            continue;
        }
        if(powmod(10,1,m)==1)
        {
            cout<<"Case "<<pl++<<": 1"<<endl;
            continue;
        }
        bignum n=oula(m);
        //cout<<"n="<<n<<endl;
        FindFac(n);
        //枚举n的所有因子
        yinzinum=0;//因子个数
        dfs(0,1);
        sort(yinzi,yinzi+yinzinum);
        yinzinum=unique(yinzi,yinzi+yinzinum)-yinzi;
        //......................
        for(int i=0;i<yinzinum;i++)
        {
            if(powmod(10,yinzi[i],m)==1)
            {
                cout<<"Case "<<pl++<<": "<<yinzi[i]<<endl;
                break;
            }
        }
    }
    return 0;
}

你可能感兴趣的:(c,测试,null,Integer,input,each)