8是中国的幸运数字,如果一个数字的每一位都由8构成则该数字被称作是幸运数字。
现在给定一个正整数L,请问至少多少个8连在一起组成的正整数(即最小幸运数字)是L的倍数。
输入格式
输入包含多组测试用例。
每组测试用例占一行,包含一个整数L。
当输入用例L=0时,表示输入终止,该用例无需处理。
输出格式
每组测试用例输出结果占一行。
结果为“Case 1: ”+一个整数N,N代表满足条件的最小幸运数字的位数。
如果满足条件的幸运数字不存在,则N=0。
数据范围
1≤L≤2∗1091≤L≤2∗109
输入样例:
8
11
16
0
输出样例:
Case 1: 1
Case 2: 2
Case 3: 0
思路:俩个乘法的积如果爆了Long long用龟速乘法
欧拉定理的使用条件为a和·n互质
合理的数学·推理化简一个计算
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL qmul(LL a, LL k, LL b){
LL res = 0;
while(k){
if (k & 1) res = (res + a) % b;
a = (a + a) % b;
k >>= 1;
}
return res;
}
LL qmi(LL a, LL k, LL b){
LL res = 1;
while(k){
if (k & 1) res = qmul(res, a, b);
a = qmul(a, a, b);
k >>= 1;
}
return res;
}
LL get_euler(LL C){
LL res = C;
for (LL i = 2; i <= C / i; i ++)
if (C % i == 0){
while (C % i == 0) C /= i;
res = res / i * (i - 1);
}
if (C > 1) res = res / C * (C - 1);
return res;
}
int main(){
int T = 1;
LL L;
while (cin >> L , L){
int d = 1;
while (L % (d * 2) == 0 && d * 2 <= 8) d = d * 2;
LL C = 9 * L / d;
LL phi = get_euler(C);
LL res = 1e18;
if (C % 2 == 0 || C % 5 == 0) res = 0;
else{
for (LL d = 1; d * d <= phi; d ++)
if (phi % d == 0){
if (qmi(10, d, C) == 1) res = min(res, d);
if (qmi(10, phi / d, C)) res = min(res, phi / d);
}
}
printf("Case %d: %lld\n", T ++, res);
}
return 0;
}