蓝桥杯A组——Python(10.04)Day6

蓝桥杯A组——Python(10.04)Day6

重新规划了题目表达W-week,T-题号

W2T1-寻找整数CRT:

   有一个不超过10的17次方的正整数n,知道这个数除以2至49后的余数如下表所示,求这个正整数最小是多少?
余数表

  刚开始没去自学 CRTextended_gcd 写了个史山代码,但胜在简单无脑。

#提前进行了质数提取和余数为零的剔除
a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
m = [1, 2, 4, 4, 0, 10, 0, 18, 15, 16, 27, 22, 1, 11, 5]

# 计算所有质数的乘积
product = 1
for p in a:
    product *= p

a1 = []  # 除a[i]外其他质数乘积
for i in range(len(a)):
    a1.append(product // a[i])

a2 = []  # 乘法逆元列表
for i in range(len(a)):
    # 使用pow函数计算模逆元
    a2.append(pow(a1[i], -1, a[i]))

n = 0
for i in range(len(a)):
    n += a1[i] * a2[i] * m[i]

n = n % product
print(n)

   %product 一开始写成了%pow(10,17) 怎么run都答案错误,我都快哭了,自学 extended_gcd 重新写了才发现问题,我是真的会谢

——————————————————————————————————

接下来是分函数写的

def extended_gcd(a, b):
    """扩展欧几里得算法,返回gcd(a, b)以及系数x, y使得ax + by = gcd(a, b)"""
    if a == 0:
        return b, 0, 1
    gcd, x1, y1 = extended_gcd(b % a, a)
    x = y1-(b//a)*x1
    y = x1
    return gcd, x, y

    欧几里得算法给我一种熟悉又陌生的感觉,求gcd可以直接用函数,一搜才发现这就是辗转相除法,简直小丑了。
    扩展欧几里得算法是求系数x, y使得ax + by = gcd(a, b),用在求逆元和之后的CRT算法里

def mod_inverse(a, m):
    """计算a在模m下的逆元,如果不存在则返回None"""
    gcd, x, y = extended_gcd(a, m)
    if gcd != 1:
        return None  # 逆元不存在,a和m不是互质的
    else:
        return x % m
def CRT(a, m):
    """中国剩余定理求解"""
    N = 1
    for n in a:
        N*=n

    result = 0
    for ai, mi in zip(a, m):
        Ni = N // ai
        inv_Ni = mod_inverse(Ni, ai)
        result += mi * Ni * inv_Ni

    return result%N
a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
m = [1, 2, 4, 4, 0, 10, 0, 18, 15, 16, 27, 22, 1, 11, 5]
# 去除m中对应a为质数但余数为0的元素
filtered_a = [x for i, x in enumerate(a) if m[i] != 0]
filtered_m = [x for x in m if x != 0]
print(CRT(filtered_a, filtered_m))

    enumerate真的好用,好评

   写代码还是以数学为基础的,本来还是两道题,但学 广义欧几里得CRT 花的时间太久了,所以今天只有一题,学 extended_gcdCRT 也算是完成学习任务了。

   出去玩回来了,国庆结束,重回学习状态,加油!

————————————————————————————————————————

W2(D6)——end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值