Форум сайта python.su
PEHDOMДа, это для всех натуральных работает. Доказательство лежит в Интернете. Так как у всех других (не коренных) делителей есть пары, чтобы произведение делителя и его пары дало само число, а у корня такой пары нет, отличной от него, то парных делителей всегда чётное количество, а у корня всегда пары нет.
число имеет нечетное количество делителей если имеет целочисленный корень
PEHDOMСогласен. В контексте компьютеров не подумал.
не проще ли, с точки зрения быстродействия, просто сразу посмотреть делиться ли число на 9 без остака?
PEHDOMЯ выше поправил своё сообщение и добавил туда ещё само число как собственный делитель, если оно нечётное. Это не условности, это на ответ влияет. Если число чётное или нечётное, то единица - один из его нечётных делителей. Если число нечётное, то само число тоже один из его нечётных делителей. Так что это существенно.py.user.nextусловности
Да и единица тоже является нечётным делителем
PEHDOMПриведи пример. А я его поломаю.
перебором оно решается делением на (от 2 до int(корня квадратного из числа))
Отредактировано py.user.next (Апрель 19, 2021 22:26:42)
Офлайн
py.user.nextЕстевенно влияет, на то они и условности (условия задачи)
Это не условности, это на ответ влияет.
py.user.nextда нечего его ломать я посмотрел там реально овердофига (в среднем каждео третье) чисел имеют менее 5-ти нечетных делителей (кроме 1 и самого себя), и любое количество четных.
Приведи пример. А я его поломаю.
from math import sqrt a_min=35000000 a_max=40000000 for i in range(a_min, a_max + 1): res = [] for d1 in range(2, int(sqrt(i))+1): if i % d1 == 0: if d1 % 2 == 1: res.append(d1) d2 = i // d1 if d2 % 2 == 1 and d2 != d1: res.append(d2) if len(res) >= 5: break if 0 < len(res) < 5: print( i,'>', res)
[code python][/code]
Офлайн
PEHDOMТы их не исключай. Если в условии явно не говорится, что единицу и само нечётное число надо исключить, то делать этого не надо.
имеют менее 5-ти нечетных делителей (кроме 1 и самого себя)
PEHDOMЗачем ускорять, это ЕГЭшная задача. Никакой там параллельности нет и никакой кучи языков там нет. Оно идёт только на алгоритм и его сложность, не более.
поэтому серьезно ускорить его можно только или распаралелив вычисления или написав на более низкоуровневом ЯП.
Офлайн
py.user.nextОсобо ничего не поменялось, в среднем каждое третьее число подходит под критерии.
Ты их не исключай. Если в условии явно не говорится, что единицу и само нечётное число надо исключить, то делать этого не надо.
py.user.nextУскорить в том плане чтобы например исключить большую часть заведомо неподходящих чисел, но тут увы ничего не выйдет так как под критерий попадает каждое третье-четверное число..
Зачем ускорять, это ЕГЭшная задача. Никакой там параллельности нет и никакой кучи языков там нет. Оно идёт только на алгоритм и его сложность, не более.
[code python][/code]
Офлайн
Вот моё лобовое решение
>>> def odd_delimiters(n): ... yield 1 ... for i in range(3, n // 2 + 1, 2): ... if n % i == 0: ... yield i ... if n % 2 != 0: ... yield n ... >>> for i in range(35000000, 35000100): ... d = set(odd_delimiters(i)) ... if len(d) < 5: ... print(i, d) ... 35000003 {1, 35000003, 12157, 2879} 35000006 {1, 17500003, 4549, 3847} 35000008 {257353, 1, 4375001, 17} 35000011 {1, 35000011} 35000012 {1, 163, 53681, 8750003} 35000015 {1, 7000003, 5, 35000015} 35000023 {1129033, 1, 35000023, 31} 35000024 {1, 2689, 1627, 4375003} 35000026 {1, 17500013} 35000027 {1, 35000027, 209581, 167} 35000029 {1, 1427, 35000029, 24527} 35000032 {1, 1093751} 35000036 {6047, 1, 8750009, 1447} 35000038 {1, 673, 26003, 17500019} 35000041 {1, 35000041} 35000044 {1, 8750011} 35000045 {1, 35000045, 7000009, 5} 35000047 {1, 211, 165877, 35000047} 35000048 {1, 2187503, 977, 2239} 35000053 {1, 11, 35000053, 3181823} 35000057 {275591, 1, 35000057, 127} 35000062 {1, 17500031} 35000066 {1, 17500033, 760871, 23} 35000067 {35000067, 1, 3, 11666689} 35000068 {1, 8750017} 35000072 {11423, 1, 4375009, 383} 35000074 {1, 17500037} 35000077 {1, 5000011, 35000077, 7} 35000078 {1, 15667, 1117, 17500039} 35000079 {1, 3, 11666693, 35000079} 35000080 {1, 2187505, 437501, 5} 35000081 {443039, 1, 35000081, 79} 35000083 {1, 35000083} 35000084 {1, 1250003, 8750021, 7} 35000086 {1, 1590913, 11, 17500043} 35000087 {1, 660379, 53, 35000087} 35000088 {1458337, 1, 3, 4375011} 35000092 {1, 143443, 61, 8750023} 35000093 {1, 35000093, 2058829, 17} 35000094 {1, 3, 5833349, 17500047} 35000096 {1, 1093753} 35000099 {1, 35000099} >>>
>>> from math import sqrt >>> >>> a_min=35000000 >>> a_max=35000100 >>> >>> for i in range(a_min, a_max + 1): ... res = [] ... for d1 in range(2, int(sqrt(i))+1): ... if i % d1 == 0: ... if d1 % 2 == 1: ... res.append(d1) ... d2 = i // d1 ... if d2 % 2 == 1 and d2 != d1: ... res.append(d2) ... if len(res) >= 5: ... break ... if 0 < len(res) < 5: ... print( i,'>', res) ... 35000001 > [3, 11666667, 9, 3888889] 35000003 > [2879, 12157] 35000006 > [17500003, 3847, 4549] 35000008 > [4375001, 17, 257353] 35000012 > [8750003, 163, 53681] 35000015 > [5, 7000003] 35000023 > [31, 1129033] 35000024 > [4375003, 1627, 2689] 35000026 > [17500013] 35000027 > [167, 209581] 35000029 > [1427, 24527] 35000032 > [1093751] 35000033 > [19, 1842107, 361, 96953] 35000036 > [8750009, 1447, 6047] 35000037 > [3, 11666679, 9, 3888893] 35000038 > [17500019, 673, 26003] 35000044 > [8750011] 35000045 > [5, 7000009] 35000047 > [211, 165877] 35000048 > [2187503, 977, 2239] 35000053 > [11, 3181823] 35000057 > [127, 275591] 35000062 > [17500031] 35000066 > [17500033, 23, 760871] 35000067 > [3, 11666689] 35000068 > [8750017] 35000072 > [4375009, 383, 11423] 35000074 > [17500037] 35000077 > [7, 5000011] 35000078 > [17500039, 1117, 15667] 35000079 > [3, 11666693] 35000080 > [5, 2187505, 437501] 35000081 > [79, 443039] 35000084 > [8750021, 7, 1250003] 35000086 > [17500043, 11, 1590913] 35000087 > [53, 660379] 35000088 > [3, 4375011, 1458337] 35000092 > [8750023, 61, 143443] 35000093 > [17, 2058829] 35000094 > [17500047, 3, 5833349] 35000096 > [1093753] >>>
Офлайн
py.user.nextэто ж был для варианта когда 1 и само число не учитывается .. а так оно выдает ровно то же результат
Твоё лобовое решение упускает много чисел, у которых меньше пяти нечётных делителей
from math import sqrt a_min=35000000 a_max=35000100 for i in range(a_min, a_max + 1): res = [1,] if i % 2 == 1: res.append(i) for d1 in range(2, int(sqrt(i))+1): if i % d1 == 0: if d1 % 2 == 1: res.append(d1) d2 = i // d1 if d2 % 2 == 1 and d2 != d1: res.append(d2) if len(res) >= 5: break if 0 < len(res) < 5: print( i,'>', res) >> 35000003 > [1, 35000003, 2879, 12157] 35000006 > [1, 17500003, 3847, 4549] 35000008 > [1, 4375001, 17, 257353] 35000011 > [1, 35000011] 35000012 > [1, 8750003, 163, 53681] 35000015 > [1, 35000015, 5, 7000003] 35000023 > [1, 35000023, 31, 1129033] 35000024 > [1, 4375003, 1627, 2689] 35000026 > [1, 17500013] 35000027 > [1, 35000027, 167, 209581] 35000029 > [1, 35000029, 1427, 24527] 35000032 > [1, 1093751] 35000036 > [1, 8750009, 1447, 6047] 35000038 > [1, 17500019, 673, 26003] 35000041 > [1, 35000041] 35000044 > [1, 8750011] 35000045 > [1, 35000045, 5, 7000009] 35000047 > [1, 35000047, 211, 165877] 35000048 > [1, 2187503, 977, 2239] 35000053 > [1, 35000053, 11, 3181823] 35000057 > [1, 35000057, 127, 275591] 35000062 > [1, 17500031] 35000066 > [1, 17500033, 23, 760871] 35000067 > [1, 35000067, 3, 11666689] 35000068 > [1, 8750017] 35000072 > [1, 4375009, 383, 11423] 35000074 > [1, 17500037] 35000077 > [1, 35000077, 7, 5000011] 35000078 > [1, 17500039, 1117, 15667] 35000079 > [1, 35000079, 3, 11666693] 35000080 > [1, 5, 2187505, 437501] 35000081 > [1, 35000081, 79, 443039] 35000083 > [1, 35000083] 35000084 > [1, 8750021, 7, 1250003] 35000086 > [1, 17500043, 11, 1590913] 35000087 > [1, 35000087, 53, 660379] 35000088 > [1, 3, 4375011, 1458337] 35000092 > [1, 8750023, 61, 143443] 35000093 > [1, 35000093, 17, 2058829] 35000094 > [1, 17500047, 3, 5833349] 35000096 > [1, 1093753] 35000099 > [1, 35000099] >>>
[code python][/code]
Отредактировано PEHDOM (Апрель 21, 2021 16:38:31)
Офлайн
PEHDOMОно ничего не меняет практически в контексте задачи. Для n = 100 мой вариант перебирает ~25 делителей, твой вариант перебирает ~10 делителей. Так что лобовое решение детерминировано, но не подходит. Как-то эта задача решается по-другому.
а у меня около 6 тысяч
Отредактировано py.user.next (Апрель 21, 2021 16:59:29)
Офлайн
py.user.nextнаверное да, но вот как? тут слишком много чисел попадает под условия задачи. и какого общего признака я у них не вижу Может стоит пойти от обратного? Типа вот у нас диапазон чисел от 35000000 до 40000000 и возможные делители от 2 до корня квадратного из 40000000. очевидно что при делителе 2 мы получим вторые делители в диапазоне от 17 500 000 до 20 500 000 из них подходящие только нечетные. Нет смысла перебирать все числа, достаточно взять только нечетные из диапазоона и посмотреть к каким числам они подходят. При 3 диапазон будет от 11 666 666 до 13 333 333 из них подходящие опять же только нечетные и само 3 ну и т д…
Так что лобовое решение детерминировано, но не подходит. Как-то эта задача решается по-другому.
[code python][/code]
Отредактировано PEHDOM (Апрель 22, 2021 11:24:05)
Офлайн
Нашёл тут у него условие дополнительное
LeeТак что единицу и само число не считаем, либо вводим, что не меньше пяти делителей, а меньше семи делителей.
Заранее спасибо.(1 и само число не считать).
PEHDOMЯ думаю, там есть какой-то период внутри последовательности, через который её можно сократить по количеству элементов, для которых уже можно применять любой лобовой алгоритм. Ну, типа как у синуса, который простирается от минус бесконечности до плюс бесконечности на оси абсцисс, но всегда можно сказать, чему равно его значение на миллиардных значениях абсцисс, так как функция периодическая и у неё везде всё повторяется.
наверное да, но вот как? тут слишком много чисел попадает под условия задачи. и какого общего признака я у них не вижу
Офлайн
py.user.nextМожет и есть но вот так явно его не видно.
Я думаю, там есть какой-то период внутри последовательности,
from math import sqrt from time import time a_min=35000000 a_max=40000000 div_count = 5 start_time = time() res ={x:[] for x in range (a_min, a_max+1)} for i in range(2, int(sqrt(a_max))+1): j_min = a_min//i if i%2==0 : #если первый делитель четный, то нас интересуют только нечетные вторыер делители, иначе - все. step = 2 if j_min%2==0: j_min +=1 else: step = 1 for j in range(j_min, a_max//i+1, step): num = i*j if num in res: if j%2 == 1: res[num].append(j) if i%2 == 1 and i!=j: res[num].append(i) if len(res[num]) >= div_count: res.pop(num) print('work end. total time:', time()-start_time) for key ,lst in res.items(): if lst: print(key, '>', lst)
[code python][/code]
Отредактировано PEHDOM (Апрель 23, 2021 16:31:01)
Офлайн