Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/103: Рейтинг темы: голосов - 103, средняя оценка - 4.63
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317

Разложение на множители

19.08.2020, 09:43. Показов 19984. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача разложения числа на простые(!) множители решается многими методами и довольно быстро.
Существует ли встроенная функция или метод для волучения всех(!) вариантов получения числа произведением других натуральных чисел.
Для себя сделал, но, например, для числа 720 время нахождения всех вариантов занимает ~ 0,3 сек
Хотелось бы быстрее
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.08.2020, 09:43
Ответы с готовыми решениями:

Разложение на множители
Добрый день. Нужно разложить число на множители в виде: 24=2*2*2*2*3. Но в программе получается результат: 24=2*2*2*3. Не знаю, откуда...

Разложение на простые множители
Требуется разложить целое число N на простые множители и вывести результат в порядке возрастания множителей с указанием степени. ...

Разложение на простые множители
Разложение на простые множители Требуется разложить целое число N на простые множители с учётом их степени и вывести результат в порядке...

31
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317
19.08.2020, 16:26  [ТС]
Студворк — интернет-сервис помощи студентам
ФедосеевПавел,
Не всегда
У 24 максимально длинное - 2, 2, 2, 3
А "верным" разложением будет - 2, 3, 4
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 18:22
для N = 997
ответ:
6696928794914170755927656556625011316008 7800731595850465234399273146940695308507 6558248986759809911329746670573470716765 7419658035576962772490360984186609252459 1048592651443658881716281639819636737213 6384565404686473871329212422972447846496 6298164321606997798554088854787768644782 89024177325354254336

что равно
Кликните здесь для просмотра всего текста
2**996


Добавлено через 4 минуты
для N = 996
996 = 2 * 2 * 3 * 83

ответ:
1523246532714432760129781760
что равно
Кликните здесь для просмотра всего текста
(2** 82) * (3**2) * (5**1) * (7**1)


или я не прав?
0
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317
19.08.2020, 19:01  [ТС]
Прав
Оба ответа верны

Добавлено через 11 минут
Полный код :
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def delit(a) :
    res = []
    i = 1
    while i * i < a + 1 :
        if a % i == 0 :
            temp = [i, a // i]
            res.append(temp)
        i += 1
    return res 
    
n = int(input())
npr = [2,3,5,7,11,13,17,19,23,29]
 
# первичное разложение на парные делители
fact = delit(n)
 
flen = len(fact)
while True :
    for j in range(flen) :
        zero = 1
 
        # если в очередном списке делителей 
        #есть "1", пропустить
        if 1 not in fact[j] :
            zero = 0
            n1 = list(fact[j])
 
            # "вытаскиваем" последний делитель из списка
            # и ищем все попарные разложения на множители
            factj = delit(n1.pop())
 
            # каждую полученную пару 
            #объединяем со списком
            for k in range(len(factj)) :
                factj[k].extend(n1)
                factj[k].sort()
                fact.append(factj[k])
    flen = len(fact)
 
    # если zero не изменилось во всех списках,
    # все варианты найдены
    if zero == 1:
        break
 
# удаляем 1 из всех вариантов
for ik in fact :
    ik.sort(reverse=True)
    if ik[-1] == 1 :
        ik.pop()
 
# удаляем одинаковые списки
fact.sort()
print(len(fact))
j =[0]
resj = []
for i in fact :
    if i != j :
        resj.append(i)
    j=i
print(len(resj))
######################################
 
minc = int(1e300) + 1
for i in resj :
    j = 0
    ss = 1
    for ii in i:
        ss *= npr[j] ** (ii-1)
        if ss > int(1e300) + 1 :
            ss = int(1e300) + 1
            break
        j += 1
    minc = min(minc,ss)
print(minc)
Проблема в том, что цикл "while True" создает, например, для 720 29 с лишним тысяч вложенных списков-вариантов множителей. После удаления одинаковых остается всего(!) 98.
Поэтому и спрашивал совета, есть ли более оптимальная возможность получения всех списков-вариантов.
При удалении внутри цикла ответ получается неверным
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 20:18
Лучший ответ Сообщение было отмечено Gdez как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def prime_divisors(n):
    a = []
    i = 2
    while i*i <= n:
        if n % i == 0:
            a.append(i)
            n //= i
        else:
            i += 1
    a.append(n)
    a.sort(reverse=True)
    return a
 
 
def solve(n):
    pr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
    res = 1
    dv = prime_divisors(n)
    for x, p in zip(pr, dv):
        res *= x**(p-1)
    return res
 
print(solve(int(input())))
8 16 24 32 48 64 72 80 96 108 112 128 144 160 162 176 192 208 216 224 243 256 272 288 304 320 324 352 368 384 416 432 448 464 480 486 496 512 544 576 592 608 640 648 656 672 688 704 729 736 752 768 832 848 864 896 928 944 960 972 976 992
для этих чисел ответ не верен.
1
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317
19.08.2020, 20:42  [ТС]
Для 8 у Вас выводит 30 - 1, 2, 3, 5, 6, 10, 15, 30
У меня 24 - 1,2,3,4,6,8,12,24
24 < 30
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 20:45
Я написал для каких чисел мой код выводит не правильный ответ.
0
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317
19.08.2020, 21:15  [ТС]
Извините, неверно подумал...

Добавлено через 28 минут
Интересно:
Из 63 "неверных" ответов 55 кратны 8
У оставшихся 7 - 2^2 * 3^3
2^1 * 3^4
2^0 * 3^5

2^2 * 3^4
2^1 * 3^5
2^0 * 3^6

2^2 * 3^5 = 972 (последнее)
2^1 * 3^6
2^0 * 3^7 - тоже не проходят
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8665 / 4502 / 1670
Регистрация: 01.02.2015
Сообщений: 13,928
Записей в блоге: 13
19.08.2020, 22:10
Увидел разбор "на бумаге" решения для N=16:

https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4
Разложим N на множители:

1. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(16-1)}=2^{15}=32768

2. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^3 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(8-1)} \cdot 3^{(2-1)}=2^{7} \cdot 3^{1}=384

3. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^2 \cdot 2^2
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(4-1)} \cdot 3^{(4-1)}=2^{3} \cdot 3^{3}=216

4. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^2 \cdot 2^1 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(4-1)} \cdot 3^{(2-1)} \cdot 5^{(2-1)}=2^{3} \cdot 3^{1} \cdot 5^{1}=120

5. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^1 \cdot 2^1 \cdot 2^1 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(2-1)} \cdot 3^{(2-1)} \cdot 5^{(2-1)} \cdot 7^{(2-1)}=2^{1} \cdot 3^{1} \cdot 5^{1} \cdot 7^{1}=210

После чего сравнивались варианты и выбирался ответ: 120.

Т.е. присутствует некоторый перебор.
Получается, что для каждого простого делителя числа N нужно получить разложение на множители и перебрать все комбинации.



-----------------------------------------------------
Тогда вижу решение таким.
Тут пригодится разложение на слагаемые.
И, видимо, для получения комбинаций для следующего простого делителя, придётся воспользоваться рекурсией.
Из итоговой комбинации получить число X и запомнить его для сравнения.

Возможно, какие-то условия могут ограничить рекурсию и сократить перебор.

Но именно это и реализовано в сообщении #23

Так что идей пока нет.
1
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,317
20.08.2020, 10:32  [ТС]
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Все таки itertools.combinations
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from itertools import combinations
#import numpy as np
 
def prime_divisors(n):
    a = []
    i = 2
    while i*i <= n:
        if n % i == 0:
            a.append(i)
            n //= i
        else:
            i += 1
    a.append(n)
    a.sort(reverse=True)
    return a
    
n = int(input())
npr = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61]
 
# поиск всех списков-вариантов множителей "n"
res =[]
# разложение на простые делители "n"
delit = prime_divisors(n)
tt =[n,1]
res.append(tt)
res.append(delit)
for i in range(2,len(delit)) :
    # все комбинации перебора делителей,
    # начиная с двух делителей до всех делителей
    data = list(combinations(delit, i))
    
    for j in data:
        jj = list(j)
        
        # здесь пытался применить prod от numpy,
        # но ниже при нахождении "ss" шло 
        # переполнение (????)
        
        # добавление к набору делителей
        # частного от "n" к произведению делителей
        temp = 1
        for k in jj:
            temp *= k
        temp1 = n//temp
        jj.append(temp1)
        jj.sort(reverse=True)
        
        # добавление набора "ttemp" из произведения 
        # делителей и частного от "n" к произведению
        # и удаление одинаковых списков-наборов
        if jj not in res:
            res.append(jj)
        ttemp = sorted([temp,temp1],reverse=True)
        if ttemp not in res:
            res.append(ttemp)
            
######################################
minc = int(1e300) + 1
for i in res :
    j = 0
    ss = 1
    for ii in i:
        ss *= npr[j] ** (ii-1)
        if ss > int(1e300) + 1 :
            ss = int(1e300) + 1
            break
        j += 1
    minc = min(minc,ss)
print(minc)
Отдельное спасибо еаа и ФедосеевПавел

Добавлено через 2 минуты
Время < 200 мсек
Память 300 KБ
N - проверял до 2*10^7, а не до 1000
1
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
20.08.2020, 11:03
Вот нашел, похожая задача:
Acmp[точка]ru
Задача 289
0
16 / 14 / 4
Регистрация: 05.06.2019
Сообщений: 79
20.08.2020, 14:00
Недавно начал изучать язык, решил попробовать написать свой вариант
Базируется на решете Эратосфена, вроде быстро, но мне кажется что это "быдлокод"
Что думаете?

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
n = int(input('n = ')) 
dev = []  #Массив ВСЕХ делителей числа. Заполняется в другом куске кода
d = int(n / 2)
mas = list(range(d+1))  #Список чисел до n/2 так как делителей > n/2 нет
primes = []  # Массив простых делителей
 
 
def prosto():
    global dev, primes
    c = len(dev)
 
    for i in range(1, c, 1): # Поиск простых чисел начиная с первого простого делителя
        if dev[i] != 0:
            primes.append(dev[i])
            for help1 in range(i, c): #Само решето. Сравнивает значения массива ВСЕХ делителей с на кратность простым числам.
 
                for j in primes:
                    if dev[help1] % j == 0:  
                        dev[help1] = 0
 
    return primes
Миниатюры
Разложение на множители  
0
16 / 14 / 4
Регистрация: 05.06.2019
Сообщений: 79
20.08.2020, 14:05
Оу, задача то в другом состоит...
Прочитал первый пост в треде и пошел писать, хех)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.08.2020, 14:05
Помогаю со студенческими работами здесь

Разложение на простые множители
Разложение на простые Требуется разложить целое число N на простые множители с учётом их степени и вывести результат в порядке...

Разложение на простые множители (Время: 1 сек. Память: 16 Мб Сложность: 27%)
Требуется вывести представление целого числа N в виде произведения простых чисел. Входные данные Входной файл INPUT.TXT содержит...

Разложение на множители
Факторизацией называется разложение произвольного натурального числа n в произведение целых положительных чисел, больших 1. Два разложения...

Разложение на простые множители (сириус)
Не могу решить казалось бы простую задачу, помогите пожалуйста с решением. (знаю что такая тема была на форуме, но от туда ничего не...

Разложение на множители
Любое число может быть единственным образом разложено на простые сомножители. Написать программу для выполнения такого разложения.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru