• 51Nod 1359 循环探求


    51Nod 1359 循环探求


    题意

    输入n和k,求最小 x (x > 1)使得 n^x % (10^k) == n % (10^k)
    n(1 <= n < 10^600)和k(1 <= k <= 600)

    做法

    由于x>1, 对原式变形有
    n * n^x % (10^k) == n % (10^k)
    则答案为x+1
    另外,还有
    n % (10^k) = n * n^x % (10^k)
    用上式进行等量代换
    n * n^x % (10^k) = (n * n^x) * n^x % (10^k) = n * (nx)2 % (10^k)
    = ...
    = n * (nx)t % (10^k)
    且 t > 1

    先考虑mod[1] = 10,找到最小的x1使得
    n * (n^x1) % mod1 == n % mod1
    由上可知
    n * (nx1)t % mod1 == n % mod1
    及给x1乘t不会影响mod1下的情况,因此令n1 = n^x1,mod2 = 100, 有
    n * n1^t % mod2 == n % mod2
    找到一个最小的t满足上式,则答案是x1*t+1

    进一步枚举k,可得到一组等式
    n * n(k-1)^xk % modk == n modk
    因此,可以递推求解。

    接下来的问题是如何找到n * (n^x1) % mod1 == n % mod1中的x1
    可以注意到,mod = 10^(k-1)时,的后k-1位两边一定相等,而mod = 10^k时,数位仅仅多了一位,因此这一位数只有10种可能,因此枚举连续11个t后一定可以进入循环之中,并枚举完所有的解,因此每次把t从1枚举到20

    由于数据的范围,这里使用python实现,需要注意,中间变量需要模10^k,来保证复杂度,否则很容易超时

    N,K = map(int,input().split(' '))
    M = 10**K
    N %= M
    n = N
    mod = 10
    ans = 1
    for k in range(1,K+1):
        flag = 0
        for xk in range(1,21):
            tmp = (n**xk) % M
            if (N * tmp) % mod == N % mod:
                flag = 1
                ans *= xk
                n = tmp
                mod = mod * 10
                break
        if flag == 0:
            ans = 0
            break
    
    print(ans+1)
    
  • 相关阅读:
    是否需要有代码规范
    结对同伴作业复审
    个人作业-四则运算生成
    个人博客-week7
    个人博客作业Week3
    结对编程项目总结
    个人项目总结
    个人博客作业Week2
    第二次结对作业
    个人作业3——个人总结(Alpha阶段)
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/13688121.html
Copyright © 2020-2023  润新知