同余----------最幸运的数字

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;
}
发布了106 篇原创文章 · 获赞 67 · 访问量 5417

猜你喜欢

转载自blog.csdn.net/qq_45772483/article/details/105027091