Time Limit: 1000MS | Memory Limit: 65536K | |
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
题意:给你一个l,找出一个最小的数m,使得m个8能被l整除,如果不能找到这个数,输出0。
题解:设数字是x,则x个8可以被l整除,因为10^x-1是x个9,所以8/9*(10^x-1)=l*p
即(10^x-1)=0*l*p/8
设m=9*l/gcd(l,8),则存在p1,使得9*l*p/8=m*p1,转化为(10^x-1)=m*p1
求10^x≡1(mode m)的最小解
根据欧拉公式,10^(φ(m))≡1(mod m),因为要求最小解,所以答案是φ(m)的因子
当gcd(L,10)!=1时,方程无解
用快速幂求解即可
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; typedef long long ll; ll phi(ll n){//欧拉函数 ll rea=n; for(ll i=2;i*i<=n;i++){ if(n%i==0){ rea=rea-rea/i; do n/=i; while(n%i==0); } } if(n>1)rea=rea-rea/n; return rea; } ll multi(ll a,ll b,ll k){//a*b%k 直接乘会爆 ll ans=0; while(b){ if(b&1){ ans=(ans+a)%k; } a=(a<<1)%k; b=b>>1; } return ans; } ll quick(ll a,ll k,ll m){//快速幂 ll ans=1; while(k){ if(k&1){ ans=multi(ans,a,m); } a=multi(a,a,m); k>>=1; } return ans; } int main(){ ll l,cas=1; while(scanf("%lld",&l)&&l){ ll m=9*l/__gcd(l,(ll)8); printf("Case %lld: ",cas++); if(__gcd((ll)10,m)!=1){//无解 printf("0\n"); continue; } ll i,x=phi(m); ll flag=0; for(i=1;i<=sqrt(x);i++){//先找1-sqrt(x)中的因子 if(x%i==0){ if(quick(10,i,m)==1){ flag=1; printf("%lld\n",i); break; } } } if(!flag){ for(i=sqrt(x);i>=2;i--){//找sqrt(x)-x的因子 if(x%i==0){ if(quick(10,x/i,m)==1){ printf("%lld\n",x/i); break; } } } } } return 0; }