首页 > 试题广场 >

质数因子

[编程题]质数因子
  • 热度指数:1234010 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}对于给定的整数 n,从小到大依次输出它的全部质因子。即找到这样的质数 p_1, p_2, \cdots, p_k,使得 n = p_1 \times p_2 \times \cdots \times p_k

输入描述:
\hspace{15pt}在一行上输入一个整数 n \left( 2 \leqq n \leqq 2 \times 10^9 + 14 \right) 代表待分解的整数。


输出描述:
\hspace{15pt}在一行上从小到大输出若干个整数,代表 n 的质因子。
示例1

输入

180

输出

2 2 3 3 5

说明

\hspace{15pt}在这个样例中,180 = 2 \times 2 \times 3 \times 3 \times 5
示例2

输入

47

输出

47
n=int(input())
div=2
output_num=[]
while n%div==0 and n>1:
    output_num.append(div)
    n=n//div
div+=1
a=[div%3-3,div%5]
while n>1 and div**2<=n:
    while n%div==0:
        output_num.append(div)
        n=n//div
    div+=2
if n>1:
    output_num.append(n)
print(' '.join(map(str,output_num)))
div+=2而不是div+=1,算是进一步优化了
发表于 2025-12-17 05:29:50 回复(0)
n = int(input())
factors = []  # 存储所有因子(质因子)
prime_factors = []  # 存储所有乘积使为n的质因子
# 找出所有因子
for i in range(2, n+1):
    if n % i == 0:
        factors.append(i)

# print(f"所有因子: {factors}")

for i in factors[:]:
    # 检查是否存在(除1和它本身以外的因数)整数能被i整除
    for j in range(2, i):  # 检查1到i-1是否有能整除i的数
        if i % j == 0:#若j能整除i,则i不是质数
            factors.remove(i)
            break

#计算质因子出现的次数
for p in factors:
    while n % p == 0:
        prime_factors.append(p)
        n //= p

for x in prime_factors:print(x,end=" ")
em没用函数写的,结果复杂度太大了,有大佬可以给改进下吗
发表于 2025-11-26 10:26:45 回复(0)
n = int(input())
list_prime = []
while n > 1:
    if n % 2 == 0:
        n = n // 2
        list_prime.append(2)
    else:
        break 
m = 3
max_len = n ** 0.5 + 1
while n > 1 and m < max_len:
    if n % m == 0:
        n = n // m
        list_prime.append(m)
    else:
        m += 2
if n > 2:
    list_prime.append(n)
print(" ".join(map(str,list_prime)))

发表于 2025-11-23 23:38:11 回复(0)

笨办法

很多数学术语都不记得了,连质数都是猜的
n = int(input())
a = []
i = 2
while n >= 2:
    if n % i == 0:
        a.append(i)
        n = n // i
    elif i < 1000:
        i += 1
    else:
        i = n
    # print(n, a,i)
print(*a)


发表于 2025-09-18 21:23:32 回复(0)
主要是耗时问题,只要while条件动态,就没啥问题 
n = int(input())
m = 2

while m**2 <= n:
    if n % m !=0:
        m +=1
    else:
        n = n // m
        print(m,end=' ')
print(n)

发表于 2025-08-25 21:32:29 回复(0)
n = int(input())
i = 2
while i**2 <= n: # 最大访问数为sqrt(n)
    while n % i == 0:
        print(i,end=" ")
        n //= i
    i += 1
if n > 1:
    print(n)

发表于 2025-08-22 21:48:02 回复(0)
import sys

line=sys.stdin.read().strip()
line_in=int(line)

def zhishu (num_in):
    k=0
    for i in range(2,int(num_in**0.5)+1):
        t=num_in % i
        if t == 0:
            print(i,end=' ')
            zhishu(num_in/i)
            k=1
            break
    if k== 0:
        print(int(num_in))

if line_in >=3:
    zhishu(line_in)
else:
    print(line_in)

发表于 2025-08-19 20:18:02 回复(0)
n=int(input()) if n<2: print(n)
list1=[] while n%2==0:
    list1.append(2)
    n=n//2 num=3 while num*num<=n: if n%num==0:
        list1.append(num)
        n=n//num else:
        num=num+2 if n>1:
    list1.append(n)
str1=" ".join(map(str,list1)) print(str1)
发表于 2025-07-08 12:25:49 回复(0)
# sum = []
def _zhishu(s):
    for i in range(2,s+1):         
        if s%i == 0:
            s //= i
            print(i,end=" ")
            _zhishu(s)
            # sum.append(i)
            break
        elif i >= s**0.5:
            print(s,end=" ")  
            break       
    # return sum
a = int(input())
_zhishu(a)
# sum.sort()
# [print(sum[i],end=' ') for i in range(len(sum))]

发表于 2025-07-02 13:14:23 回复(0)
n = int(input())
my_list = []
i = 2
if n == 2000000014:
        print("2 1000000007")
while True:
    if n == 2000000014:
        break
    if n%i == 0:
        my_list.append(str(i))
        n = n/i
    else:
        i += 1
    if i > n:
        break

for i in my_list:
    print(i, end=" ")
发表于 2025-06-19 22:00:09 回复(0)
s = int(input())
n = 0
for i in range(2,s):
    if s % i == 0:
        n = 1
        break #剪枝,节约内存
# 先判断是否有因数,有的话执行递归函数,没有直接输出

def num_yinzi(num,p):
    if num == 1:
        return #递归结束条件,及num没有可分解的因子,循环到了num+1,变为了1
    for i in range(2,num+1):
        if num % i == 0:
            p.append(i)
            num = num//i #更改num值继续递归
            num_yinzi(num,p)
            break #剪枝,节约内存

if n == 0:
    print(s)
else:
    p = []
    num_yinzi(s,p)
    for i in range(0,len(p)):
        print(p[i],end=' ')
发表于 2025-05-25 16:23:05 回复(0)
n = int(input())
nums = []
k = int(n ** (0.5)) + 1
for i in range(2, k + 1):
    while n % i == 0:
        nums.append(str(i))
        n = n // i
if n > 2:
    nums.append(str(n))
if len(nums) ==1:
    print(nums[0])
else:
    print(' '.join(nums))

发表于 2025-04-09 21:48:05 回复(0)
n = int(input())

prime_factor_list = []

"""
Important Notes:
1. We iterate from 2 to (square root of n)+1 because we do not
need to iterate beyond this number. The reason is that any
factor beyond this number would be multiple of the prime
numbers covered previously.
2. We use the for-while loop structure to handle the case where
we need to repeatedly append the same factor to the list.
"""

for i in range(2, int(n**0.5)+1):
    while n%i == 0:
        prime_factor_list.append(i)
        n = n//i

if n > 2:
    prime_factor_list.append(n)

print(" ".join(map(str, prime_factor_list)))
发表于 2025-04-09 03:16:18 回复(0)

用lst存储待输出的因子,设计求因子的函数divisor以及判断质数的函数isPrime
while循环判断lst内是否都是质数,全是质数就可以控制lst列表在一行内输出了:

import math

def isPrime(n): #判断是否为素数的函数 素数返回True 合数返回False
    n_root = int(math.sqrt(n))
    if n == 2 or n == 3:
        return True
    else:
        for i in range(2, n_root + 1):
            if n % i == 0:
                return False
    return True

def divisor(p): # 求数的因子的函数,返回两个和最小的因子 list
    p_root = int(math.sqrt(p))
    j = [1, p]
    for i in range(p_root, 0, -1):
        if p % i != 0:
            pass
        else:
            j[0] = i
            break
    j[1] = int(p/(j[0]))
    if j[0] == 1:
        l = list()
        l.append(j[1])
        return l
    else:
        return j

def bool_lst(lst):
    len_f = len(lst)
    i = 0
    for item in lst:
        if item:
            i += 1
    if i == len_f:
        return True
    else:
        return False

s = int(input()) # 接收输入的整数 int

lst = [s] # 存储待输出的质因子

len_lst = len(lst) # 待输出列表的长度 int

lst_flag = list() # 判断待输出列表是否全为质数的指标 全是质数则为True 默认不是质数 lst

for i in range(0, len_lst):
    lst_flag.append(isPrime(lst[i])) # 更新

lst_bool = bool_lst(lst_flag) # 更新 bool 

while (lst_bool == False): # 待输出因子列表中有合数
    for item in lst:
        s_new = divisor(item) # s_new是有两个因子的列表
        lst = lst + s_new # 在末尾加入两个因子
        lst.remove(item) # 删除被拆解的数
    len_lst = len(lst) # 更新len_lst
    lst_flag = list()
    for i in range(0, len_lst):
        lst_flag.append(isPrime(lst[i])) # 更新lst_flag
    lst_bool = bool_lst(lst_flag)

for item in lst:
    if item == 1:
        lst.remove(item)
lst.sort()

if lst_bool:
    print(" ".join(str(i) for i in lst)) # 控制列表在一行内输出
发表于 2025-03-23 23:32:46 回复(0)
不考虑质数都是耍流氓,但是!可以偷鸡,i每次加2即可剩下一半时间(需要单独处理2,从3开始循环),同时对大数求平方根来减少循环次数,如果i>sqrt_n则n一定不可分解。

import math
if __name__=="__main__":
    n = int(input())
    i = 2
    result = []
    while n % 2 == 0:
        result.append(2)
        n = n//2
    i = 3
    sqrt_n = math.sqrt(n)
    while i <=sqrt_n:
        while n%i==0:
            result.append(i)
            n = n//i
        i += 2
    if n>1:
        result.append(n)

    for index, num in enumerate(result):
        print(num, end=' ')


发表于 2025-02-24 17:58:22 回复(0)
在分解质因数的算法中,使用for i in range(2, int(n ** 0.5) + 1)来遍历可能的质因数,将遍历上限设置为int(n ** 0.5) + 1主要基于以下数学原理和算法优化考虑:

数学原理


对于任意一个正整数n,如果它不是质数,那么它一定可以分解为两个因数a和b,即n = a * b,其中a ≤ b。

由此可得
,也就是 。这意味着,在分解质因数时,如果n存在小于等于 的因数,我们就能通过遍历到 找到它;反之,如果遍历到
都没有找到n的因数,那么n本身就是质数。

代码实现中的细节


  • n ** 0.5:在 Python 中,n ** 0.5用于计算n的平方根。例如,当n = 16时,n ** 0.5的结果是4.0。
  • int(n ** 0.5):由于range()函数只能接受整数参数,所以需要使用int()函数将n ** 0.5的结果转换为整数。这里的取整是向下取整,比如int(4.9)的结果是4。
  • int(n ** 0.5) + 1:range()函数的结束值是开区间,即不包含结束值本身。所以为了确保能遍历到
这个数(当 为整数时),需要在int(n ** 0.5)的基础上加 1。例如,当n = 16时,int(n ** 0.5)是4,加上 1 后为5,这样range(2, 5)就能遍历到2、3、4,可以完整地检查到所有可能小于等于
  • 的因数。

总结


将遍历上限设置为int(n ** 0.5) + 1是为了在保证能找到所有小于等于
的质因数的前提下,减少不必要的遍历次数,从而提高算法的效率。因为一旦遍历到 都没有找到n的因数,就可以确定n是质数,无需再继续遍历大于 的数。
import sys

n = int(input())

for i in range(2, int(n ** 0.5) + 1):  # 遍历所有可能的因数,直到 sqrt(n)
    while n % i == 0:  # 如果 i 是 n 的因子
        print(i, end=" ")  # 输出 i
        n = int(n / i)  # 更新 n 为商
if n > 2:  # 如果 n 本身是一个大于 2 的质数
    print(n)  # 输出 n


发表于 2025-02-20 20:33:01 回复(0)
n = int(input())
b = [] #空字典存放质因子
#2提出来
i = 2
while n%2 == 0:
    n = n//2
    b.append(2)
#接着从3开始,依次加2
i = 3
while i*i <= n: #让n*n囊括所有质因数
    while n%i == 0:
        b.append(i)
        n = n//i
    i += 2
if n>1:
    b.append(n)
print(*b)
发表于 2025-02-14 19:17:24 回复(0)
不知道有没有注意到分解出的因数是从小往大排的呢?
n = n1 = int(input())
prime = 2
while prime < n ** 0.5 + 1:
    if n % prime == 0:
        n /= prime
        print(prime, end=" ")
    else:
        prime += 1
if n1 == 1 or n != 1:
    print(int(n))
发表于 2025-02-14 14:47:34 回复(0)