POJ3696 The Luckiest number题解

题目

题目描述

原题

英文题目

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

中文题意

给定一个正整数 L L L( L ⩽ 2 × 1 0 9 L\leqslant 2\times10^9 L2×109)
问至少有多少个 8 8 8连在一起组成的正整数是 L L L的倍数

输入输出格式

输入格式

每行一个正整数 L L L( L ⩽ 2 × 1 0 9 L\leqslant 2\times10^9 L2×109)

输出格式

对于每个 L L L,输出至少有多少个 8 8 8连在一起组成的正整数是 L L L的倍数,格式参照样例。若不存在,输出 0 0 0

输入输出样例

输入样例

8
11
16
0

输出样例

Case 1: 1
Case 2: 2
Case 3: 0

题解

n n n 8 8 8连在一起组成的正整数可以记为 8 9 ( 1 0 x − 1 ) \frac{8}{9}(10^x-1) 98(10x1)
所以题目就转化为求最小的 x x x使得 L ∣ 8 9 ( 1 0 x − 1 ) L|\frac{8}{9}(10^x-1) L98(10x1)
d = g c d ( L , 8 ) d=gcd(L,8) d=gcd(L,8)
L ∣ 8 9 ( 1 0 x − 1 )    ⟺    9 L ∣ 8 ( 1 0 x − 1 )    ⟺    9 L d ∣ 1 0 x − 1    ⟺    1 0 x ≡ 1 ( m o d 9 L d ) L|\frac{8}{9}(10^x-1)\iff9L|8(10^x-1)\iff\frac{9L}{d}|10^x-1\iff10^x\equiv1\pmod{\frac{9L}{d}} L98(10x1)9L8(10x1)d9L10x110x1(modd9L)
这题的关键在于一个结论:若正整数 a , n a,n a,n互质,则满足 a x ≡ 1 ( m o d n ) a^x\equiv1\pmod{n} ax1(modn)的最小整数 x 0 x_0 x0 φ ( n ) \varphi(n) φ(n)的约数
证明:
假设满足 a x ≡ 1 ( m o d n ) a^x\equiv1\pmod{n} ax1(modn)的最小整数 x 0 x_0 x0不能整除 φ ( n ) \varphi(n) φ(n)
φ ( n ) = q x 0 + r ( 0 ⩽ r &lt; x 0 ) \varphi(n)=qx_0+r(0\leqslant r&lt;x_0) φ(n)=qx0+r(0r<x0)
∵ a x 0 ≡ 1 ( m o d n ) \because a^{x_0}\equiv1\pmod{n} ax01(modn)
∴ a q x 0 ≡ 1 ( m o d n ) \therefore a^{qx_0}\equiv1\pmod{n} aqx01(modn)
∵ a φ ( n ) ≡ 1 ( m o d n ) \because a^{\varphi(n)}\equiv1\pmod{n} aφ(n)1(modn)(欧拉定理)
∴ a r ≡ 1 ( m o d n ) \therefore a^{r}\equiv1\pmod{n} ar1(modn),与 x 0 x_0 x0最小矛盾!
∴ \therefore 假设不成立,原命题成立

所以,我们只需要求出 φ ( 9 L d ) \varphi(\frac{9L}{d}) φ(d9L),时间复杂度 Θ ( L l n L ) \Theta(\sqrt{L}lnL) Θ(L lnL)
代码如下:

#include<algorithm>
#include<iostream>
using namespace std;
long long a[500000],n,p,ans,i;
int t,m;
long long gcd(long long a,long long b)
{
	return b?gcd(b,a%b):a;
}
long long phi(long long n)
{
	long long i,m=n;
	for(i=2;i*i<=n;i++) if(n%i==0){
		m=m/i*(i-1);
		while(n%i==0) n/=i;
	}
	if(n>1) m=m/n*(n-1);
	return m;
}
long long mul(long long a,long long b)
{
	a%=n,b%=n;
	long long c=(long double)a*b/n;
	long long ans=a*b-c*n;
	if (ans<0) ans+=n;
	else if(ans>=n) ans-=n;
	return ans;
}
long long power(long long a,long long b)
{
	long long c=1;
	for(;b;b>>=1){
		if(b&1) c=mul(c,a);
		a=mul(a,a);
	}
	return c;
}
int main()
{
	while(cin>>n&&n){
		n=9*n/gcd(8,n);
		cout<<"Case "<<++t<<": ";
		if(gcd(10,n)==1){
			p=phi(n);
			m=0;
			for(i=1;i*i<=p;i++) if(p%i==0){
				a[++m]=i;
				if(i*i!=p) a[++m]=p/i;
			}
			sort(a+1,a+m+1);
			for(i=1;i<=m;i++) if(power(10,a[i])==1) break;
			cout<<a[i]<<endl;
		}
		else cout<<"0"<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值