PAT1 1015 Reversible Primes

题目链接
我的github

题目大意

给两个正整数 N N N( < 1 0 5 <10^5 105)和 D D D( 1 < D ≤ 10 1<D \leq 10 1D10),判断 N , D N,D N,D是不是翻转质数,翻转质数定义如下:

  • N N N是质数
  • N N N转成 D D D进制后将其逆序,然后再变成10进制,所得的数也是质数

输入

每组包含几个测试用例,每个测试用例一行有两个整数 N , D N,D N,D,每组最后一行是一个负数

输出

对每个测试用例,如果 N , D N,D N,D是翻转质数就在一行里输出Yes,否则在一行里输出No

输入样例

73 10
23 2
23 10
-2

输出样例

Yes
Yes
No

解析

意思很好懂,就是先判断 N N N是不是质数,再将 N N N转成 D D D进制然后逆序再转成10进制,并判断转完之后的数是不是质数,如果都是质数就输出Yes否则输出No
但是在判断是否是质数的算法上有很多选择:

  • 普通的从2遍历到sqrt(n),时间复杂度是O( n \sqrt n n )
  • 从2到sqrt(n)每6个判断一次, 时间复杂度也是O( n \sqrt n n ),但是要比上面的那种更快
  • Miller-Rabin算法,时间复杂度是O( l o g n logn logn)

为了更快,我选择了Miller-Rabin算法,这个算法要求知道费马小定理,同时会快速幂的算法。所以学这个算法等于学了两个算法+一个定理,太值了

n, d = 0, 0


def trans(n, d):    #进制转换
    res = list()
    while n > 0:
        res.append(n % d)
        n //= d
    tmp = 0
    for i in range(len(res)):
        tmp *= d
        tmp += res[i]
    return tmp


def quickPow(a, i, n):  #快速幂
    if i == 0:
        return 1 % n
    temp = quickPow(a, i >> 1, n)
    temp = temp * temp % n
    if i & 1:
        temp = temp * a % n
    return temp


def test(n, a, d):  #Miller-Rabin测试
    if n == 2 or n == a:
        return True
    if (n & 1) == 0:
        return False
    while not (d & 1):
        d >>= 1
    t = quickPow(a, d, n)
    while d != n - 1 and t != 1 and t != n - 1:
        t = t * t % n
        d <<= 1
    return t == n - 1 or d & 1


def isPrime(n):
    if n < 2:
        return False
    a = [2, 3, 17, 23, 73, 19, 11, 61]  #多次进行测试以保证正确率
    for i in range(len(a)):
        if not test(n, a[i], n - 1):
            return False
    return True


def solve():
    global n, d
    while True:
        s = list(map(int, input().split()))
        if s[0] < 0:
            return
        n, d = s[0], s[1]
        if isPrime(n) and isPrime(trans(n, d)):
            print("Yes")
        else:
            print("No")


if __name__ == "__main__":
    solve()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值