ACWING202. 最幸運的數字(歐拉定理)

8是中國的幸運數字,如果一個數字的每一位都由8構成則該數字被稱作是幸運數字。

現在給定一個正整數L,請問至少多少個8連在一起組成的正整數(即最小幸運數字)是L的倍數。

輸入格式
輸入包含多組測試用例。

每組測試用例佔一行,包含一個整數L。

當輸入用例L=0時,表示輸入終止,該用例無需處理。

輸出格式
每組測試用例輸出結果佔一行。

結果爲“Case 1: ”+一個整數N,N代表滿足條件的最小幸運數字的位數。

如果滿足條件的幸運數字不存在,則N=0。

數據範圍
1≤L≤2∗109
輸入樣例:
8
11
16
0
輸出樣例:
Case 1: 1
Case 2: 2
Case 3: 0

思路:
令 d = gcd(L,8)
x個8連在一起表示爲8*(10x-1)/9,要求一個最小的x滿足
L|8*(10x-1)/9
即 9L/d | 10x-1
即 10x \equiv 1 (mod 9L/d)

由歐拉定理
aphi(n) \equiv 1 (mod n)
當a與n互質時

那麼對於 10x \equiv 1 (mod 9L/d)
當 10 與 9L/d互質時,易得x是phi(9L/d)的約數。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

typedef long long ll;

const int maxn = 1e6;

ll qmul(ll n,ll m,ll p) {
    ll res = 0;
    while(m) {
        if(m & 1) res = (res + n) % p;
        n = n * 2 % p;
        m >>= 1;
    }
    return res;
}

ll qpow(ll x,ll n,ll p) {
    ll res = 1;
    while(n) {
        if(n & 1) res = qmul(res,x,p);
        n >>= 1;
        x = qmul(x,x,p);
    }
    return res;
}

ll phi(ll n) {
    ll ans = n;
    for(ll i = 2;i * i <= n;i++) {
        if(n % i == 0) {
            ans = ans / i * (i - 1);
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1) ans = ans / n * (n - 1);
    return ans;
}

ll gcd(ll n,ll m) {
    return m == 0 ? n : gcd(m,n % m);
}


ll solve(ll p,ll mod) {
    int ans = 0;
    ll s = sqrt(1.0 * p);
    for(ll i = 1;i <= s;i++) {
        if(p % i == 0) {
            if(qpow(10ll,i,mod) == 1) {
                return i;
            }
        }
    }

    for(ll i = s - 1;i >= 1;i--) {
        if(p % i == 0) {
            if(qpow(10ll,p / i,mod) == 1) {
                return p / i;
            }
        }
    }
    return 0;
}

int main() {
    ll L;
    int kase = 0;
    while(~scanf("%lld",&L) && L) {
        ll d = gcd(L,8);
        ll mod = 9 * L / d;
        ll p = phi(mod);
        printf("Case %d: ",++kase);

        if(gcd(mod,10) != 1) {
            printf("0\n");
            continue;
        }
        ll ans = solve(p,mod);
        printf("%lld\n",ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章