因子化简——CSP认证题目

问题描述

小 P 同学在学习了素数的概念后得知,任意的正整数 n都可以唯一地表示为若干素因子相乘的形式。如果正整数 n有m 个不同的素数因子 p 1 , p 2 , … , p m p_1, p_2, \ldots, p_m p1,p2,,pm,则可以表示为: n = p 1 t 1 ⋅ p 2 t 2 ⋅ p 3 t 3 ⋯ p m t m n = p_1^{t_1} \cdot p_2^{t_2} \cdot p_3^{t_3} \cdots p_m^{t_m} n=p1t1p2t2p3t3pmtm
小 P 认为,每个素因子对应的指数 t i t_{i} ti 反映了该素因子对于 n的重要程度。现设定一个阈值 k,如果某个素因子 pi对应的指数 t i t_{i} ti小于 k,则认为该素因子不重要,可以将 p i t i p_i^{t_i} piti 项从 n 中除去;反之则将 p i t i p_i^{t_i} piti 项保留。最终剩余项的乘积就是 n简化后的值,如果没有剩余项则认为简化后的值等于1。
试编写程序处理 q个查询:
每个查询包含两个正整数 n 和 k,要求计算按上述方法将 n 简化后的值。

输入格式

从标准输入读入数据。
输入共 q+1 行。
输入第一行包含一个正整数 q,表示查询的个数。
接下来 q 行每行包含两个正整数 n 和 k,表示一个查询。

输出格式

输出到标准输出。
输出共 q行。
每行输出一个正整数,表示对应查询的结果。
样例输入
3
2155895064 3
2 2
10000000000 10
样例输出
2238728
1
10000000000

def simplify_number(n, k):
    """
    将正整数 n 按照阈值 k 简化后的值
    """
    result = 1
    i = 2
    while i * i <= n:
        if n % i == 0:
            count = 0
            while n % i == 0:
                n //= i
                count += 1
            if count >= k:  # 只保留指数不小于 k 的素数因子
                result *= i ** count
        i += 1
    if n > 1 and k==1:  # 处理最后一个素数因子,因为最后一个素数因子指数肯定为1,所以只有k为1时才保留
        result *= n
    return result

# 读取查询个数
q = int(input())

# 存储查询数据
queries = []
for _ in range(q):
    n, k = map(int, input().split())
    queries.append((n, k))

# 处理每个查询并输出结果
results = []
for query in queries:
    n, k = query
    result = simplify_number(n, k)
    results.append(result)

# 输出结果
for result in results:
    print(result)

解题思路:
以上代码的核心思路如下:

  1. 定义一个函数 simplify_number(n, k),用于将正整数 n 按照阈值 k 进行简化。
  2. 在主循环中,从最小的素数 2 开始遍历,直到 i * i 大于 n。如果 n 能够整除当前的素数 i,则统计该素数在 n 中的指数 count。
  3. 如果 count 大于等于 k,则将当前素数及其指数乘入结果中。
  4. 处理完所有小于 sqrt(n) 的素数后,如果 n 大于 1 且 k 等于 1,则将剩余的 n 乘入结果中。
  5. 对每个查询,读取输入的 n 和 k,并调用 simplify_number(n, k) 函数,将结果存入列表中。
  6. 最后,输出所有结果。
  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

STRUGGLE_xlf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值