P3685 8数
时间限制 : - MS 空间限制 : 65536 KB
评测说明
: 时限:1000ms

问题描述
给一个正整数N,问是否存在N的倍数M,且M的各个位全部由数字8组成,如果存在多个取最小的M
并输出M由几个8组成。
输入格式
一行,一个整数N
输出格式
一行一个整数,表示所求的结果。
如果无解,输出0
样例输入 1
8
样例输出 1
1
样例输入 2
11
样例输出 2
2
样例输入 3
16
样例输出 3
0
样例输入 4
18
样例输出 4
9
思路:根据题意,求t*n=8...8(k个8)的最小k.
8....8(k个8)=8/9*(10^k-1).
t*n=8/9*(10^k-1).
8/9*(10^k-1)≡ 0 (mod n)
8*(10^k-1)=9*n*t
此时求出8和9*n的最大公约数
d=gcd(8,9*n);
式子可以化简为 8/d*(10^k-1)=(9*n)/d*t
令p=8/d q=9*n/d
那么式子可化为 p*(10^k-1)=q*t
因为p,q为8/d和(9*n)/d,d又是最大公约数,所以p,q一定互质
而式子左右又相等,那么q|(10^k-1)
即 (10^k-1) ≡ 0 (mod q)
10^k≡ 1 (mod q)
由欧拉定理得a^phi(q)≡ 1(mod q)(其中gcd(a,q)==1)
所以如果10与q不互质,那么一定无解
由幂的周期性得:10^(k*t+r)≡ 1 (mod q)
又因为10^0≡ 1 (mod q)
故r==0
10^(k*t)≡ 1 (mod q)
又因为a^phi(q)≡ 1(mod q)是一组解
所以k*t==phi(q)
枚举phi(q)的因数,找出符合10^(s)≡ 1 (mod q)的最小的s即可
(其中s为phi(q)的因数)
注意:nkoj要用快速乘法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 1000000000000000000LL
using namespace std;
long long q;
long long ksc(long long x,long long y,long long N){
long long ans;
for(ans=0;y;x=(x<<1)%N,y=(y>>1))
if(y&1)ans=(ans+x)%N;
return ans;
}
long long gcd(long long a,long long b){
if(b==0)return a;
else return gcd(b,a%b);
}
long long mont(long long a,long long b,long long c){
long long ans=1;
a=a%c;
while(b>0){
if(b&1)ans=ksc(ans,a,c);
b=b>>1;
a=ksc(a,a,c);
}
return ans;
}
long long phi(long long x){
long long i,ans=x,a=x;
for(i=2;i*i<=a;i++){
if(a%i==0){
ans=ans-ans/i;
while(a%i==0)a/=i;
}
}
if(a>1)ans=ans-ans/a;
return ans;
}
bool check(long long x){
if(mont(10,x,q)==1)return true;
else return false;
}
int main(){
long long d,p,n,i,j,fi,m,minn;
cin>>n;
if(n==1||n==2||n==4||n==8){
cout<<"1";return 0;
}
d=gcd(8,9*n);
p=8/d;
q=9*n/d;
fi=phi(q);
//cout<<fi<<endl;
if(gcd(10,q)!=1){
cout<<"0";return 0;
}
m=floor(sqrt(fi)+0.5);
minn=fi;
for(i=2;i<=m;i++){
if(fi%i==0){
if(check(i)){
cout<<i;
return 0;
}
if(check(fi/i)){
minn=min(minn,fi/i);
}
}
}
cout<<minn;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 1000000000000000000LL
using namespace std;
long long q;
long long ksc(long long x,long long y,long long N){
long long ans;
for(ans=0;y;x=(x<<1)%N,y=(y>>1))
if(y&1)ans=(ans+x)%N;
return ans;
}
long long gcd(long long a,long long b){
if(b==0)return a;
else return gcd(b,a%b);
}
long long mont(long long a,long long b,long long c){
long long ans=1;
a=a%c;
while(b>0){
if(b&1)ans=ksc(ans,a,c);
b=b>>1;
a=ksc(a,a,c);
}
return ans;
}
long long phi(long long x){
long long i,ans=x,a=x;
for(i=2;i*i<=a;i++){
if(a%i==0){
ans=ans-ans/i;
while(a%i==0)a/=i;
}
}
if(a>1)ans=ans-ans/a;
return ans;
}
bool check(long long x){
if(mont(10,x,q)==1)return true;
else return false;
}
int main(){
long long d,p,n,i,j,fi,m,minn;
cin>>n;
if(n==1||n==2||n==4||n==8){
cout<<"1";return 0;
}
d=gcd(8,9*n);
p=8/d;
q=9*n/d;
fi=phi(q);
//cout<<fi<<endl;
if(gcd(10,q)!=1){
cout<<"0";return 0;
}
m=floor(sqrt(fi)+0.5);
minn=fi;
for(i=2;i<=m;i++){
if(fi%i==0){
if(check(i)){
cout<<i;
return 0;
}
if(check(fi/i)){
minn=min(minn,fi/i);
}
}
}
cout<<minn;
}