Acwing202. 最幸运的数字

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Acwing202. 最幸运的数字相关的知识,希望对你有一定的参考价值。

Acwing202. 最幸运的数字

题意:

现在给定一个正整数 L,请问至少多少个 8 连在一起组成的正整数(即最小幸运数字)是 L 的倍数。

题解:

x个8连在一起组成的正整数可写作 8 ( 1 0 x − 1 ) / 9 8(10^x-1)/9 8(10x1)/9。现在要求一个最小的x,满足 L ∣ 8 ( 1 0 x − 1 ) 9 L|\\frac{8(10^x-1)}{9} L98(10x1).
L ∣ 8 ( 1 0 x − 1 ) 9 L|\\frac{8(10^x-1)}{9} L98(10x1)= 9 L ∣ 8 ( 1 0 x − 1 ) 9L|8(10^x-1) 9L8(10x1)
我们设d=gcd(L,8)
有:gcd(L/d,8/d)=1
说明8/d与L/d互质
8(10^x-1)是9L的质数,有 9 L d ∣ 8 d ( 1 0 x − 1 ) \\frac{9L}{d}|\\frac{8}{d}(10^x-1) d9Ld8(10x1)
因为8/d与L/d互质,所以 9 L d ∣ ( 1 0 x − 1 ) \\frac{9L}{d}|(10^x-1) d9L(10x1)
再推导有: 1 0 x ≡ 1 (   m o d   9 L d ) 10^x \\equiv1 (\\bmod \\frac{9L}{d}) 10x1(modd9L)
引理:
若正整数a,n互质,则满足 a x ≡ 1 (   m o d   n ) a^x\\equiv 1(\\bmod n) ax1(modn)的最小正整数x0是 ϕ ( n ) 的 约 数 \\phi(n)的约数 ϕ(n)
所以我们只需要求出欧拉函数 ϕ ( 9 L d ) \\phi(\\frac{9L}{d}) ϕ(d9L),枚举它的所有约数,用快速幂判断是否符合条件即可。时间复杂度是 O ( L log ⁡ L ) O(\\sqrt{L}\\log{L}) O(L logL)
时间没问题,但是注意,你的longlong会被下面数据爆掉,所以要用到一个小技巧,叫龟速乘

1999999999
1213131311
1242342334
0

龟速乘其实就是把快速幂中乘法部分展开,将乘法转成加法做,每次运算都取mod,这样就不会爆

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);
}
template <typename T> inline void write(T x)
{
    if (x < 0) {
        x= ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef LOCAL
    startTime= clock();
    freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{
#ifdef LOCAL
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
ll mul(ll a, ll b, ll mod)
{
    ll ans= 0;
    while (b) {
        if (b & 1)
            ans= (ans + a) % mod;
        a= (a + a) % mod;
        b>>= 1;
    }
    return ans;
}
ll poww(ll a, ll b, ll mod)
{
    ll ans= 1;
    while (b) {
        if (b & 1)
            ans= mul(ans, a, mod) % mod;
        a= mul(a, a, mod) % mod;
        b>>= 1;
    }
    return ans % mod;
}
ll phi(ll n)
{
    ll ans= n;
    for (int i= 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            ans= ans / i * 1ll * (i - 1);
            while (n % i == 0)
                n/= i;
        }
    }
    if (n > 1)
        ans= ans / n * 1ll * (n - 1);
    return ans;
}
int main()
{
    //rd_test();
    ll l;
    int cas= 0;
    while (cin >> l) {
        if (l == 0)
            break;
        ll mod= l / __gcd(8ll, l) * 9ll;
        ll p= phi(mod);
        ll ret= 1e18;
        for (ll x= 1; x <= sqrt(p); x++) {
            if (p % x != 0)
                continue;
            if (poww(10, x, mod) == 1)
                ret= min(ret, x);
            if (poww(10, p / x, mod) == 1)
                ret= min(ret, p / x);
        }

        printf("Case %d: ", ++cas);
        printf("%lld\\n", ret == 1e18 ? 0 : ret);
    }
    return 0;
    //Time_test();
}

以上是关于Acwing202. 最幸运的数字的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 1775. 丢失的牛(简单模拟)

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

幸运数字

三:排序-幸运数字