Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 19, 2021 22:20:19

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9740
Репутация: +  843  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

PEHDOM
число имеет нечетное количество делителей если имеет целочисленный корень
Да, это для всех натуральных работает. Доказательство лежит в Интернете. Так как у всех других (не коренных) делителей есть пары, чтобы произведение делителя и его пары дало само число, а у корня такой пары нет, отличной от него, то парных делителей всегда чётное количество, а у корня всегда пары нет.
То есть, например, возьмём число 27. У него есть делитель 3, но у этого делителя есть пара, чтобы можно было получить число 27 при произведении - 9. Так мы получили пару делителей (3, 9) числа 27. И все его пары - это {{1, 27}, {3, 9}}. А число 25 имеет пару делителей (1, 25) и делитель 5, у которого нет пары, отличной от него. И все его пары - это {{1, 25}}, а делитель 5 пары не образует ни с каким.

PEHDOM
не проще ли, с точки зрения быстродействия, просто сразу посмотреть делиться ли число на 9 без остака?
Согласен. В контексте компьютеров не подумал. Мозги в математике были.

PEHDOM
py.user.next
Да и единица тоже является нечётным делителем
условности
Я выше поправил своё сообщение и добавил туда ещё само число как собственный делитель, если оно нечётное. Это не условности, это на ответ влияет. Если число чётное или нечётное, то единица - один из его нечётных делителей. Если число нечётное, то само число тоже один из его нечётных делителей. Так что это существенно.

PEHDOM
перебором оно решается делением на (от 2 до int(корня квадратного из числа))
Приведи пример. А я его поломаю.



Отредактировано py.user.next (Апрель 19, 2021 22:26:42)

Офлайн

#2 Апрель 21, 2021 09:46:06

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

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]
Бериегите свое и чужое время.

Офлайн

#3 Апрель 21, 2021 10:32:00

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9740
Репутация: +  843  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

PEHDOM
имеют менее 5-ти нечетных делителей (кроме 1 и самого себя)
Ты их не исключай. Если в условии явно не говорится, что единицу и само нечётное число надо исключить, то делать этого не надо.

PEHDOM
поэтому серьезно ускорить его можно только или распаралелив вычисления или написав на более низкоуровневом ЯП.
Зачем ускорять, это ЕГЭшная задача. Никакой там параллельности нет и никакой кучи языков там нет. Оно идёт только на алгоритм и его сложность, не более.



Офлайн

#4 Апрель 21, 2021 11:31:38

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

py.user.next
Ты их не исключай. Если в условии явно не говорится, что единицу и само нечётное число надо исключить, то делать этого не надо.
Особо ничего не поменялось, в среднем каждое третьее число подходит под критерии.

py.user.next
Зачем ускорять, это ЕГЭшная задача. Никакой там параллельности нет и никакой кучи языков там нет. Оно идёт только на алгоритм и его сложность, не более.
Ускорить в том плане чтобы например исключить большую часть заведомо неподходящих чисел, но тут увы ничего не выйдет так как под критерий попадает каждое третье-четверное число..



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#5 Апрель 21, 2021 14:59:35

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9740
Репутация: +  843  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

Вот моё лобовое решение

  
>>> 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]
>>>



Офлайн

#6 Апрель 21, 2021 16:23:10

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

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]
>>> 
только ты перебираешь порядка 9 миллионов делителей для каждого числа (при условии конечно что перебор дойдет до конца)
range(3, n // 2 + 1, 2): #35000000/2/2=8750000
а у меня около 6 тысяч
range(2, int(sqrt(i))+1): #int(sqrt(35000000))= 5 916



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Апрель 21, 2021 16:38:31)

Офлайн

#7 Апрель 21, 2021 16:53:33

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9740
Репутация: +  843  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

PEHDOM
а у меня около 6 тысяч
Оно ничего не меняет практически в контексте задачи. Для n = 100 мой вариант перебирает ~25 делителей, твой вариант перебирает ~10 делителей. Так что лобовое решение детерминировано, но не подходит. Как-то эта задача решается по-другому.

Да, ты оптимизировал, но зачем? Что дала оптимизация? Ничего. Как оно не считало 35000000 - 40000000, так оно и не считает их. Замучаешься ждать.



Отредактировано py.user.next (Апрель 21, 2021 16:59:29)

Офлайн

#8 Апрель 22, 2021 11:13:32

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

py.user.next
Так что лобовое решение детерминировано, но не подходит. Как-то эта задача решается по-другому.
наверное да, но вот как? тут слишком много чисел попадает под условия задачи. и какого общего признака я у них не вижу Может стоит пойти от обратного? Типа вот у нас диапазон чисел от 35000000 до 40000000 и возможные делители от 2 до корня квадратного из 40000000. очевидно что при делителе 2 мы получим вторые делители в диапазоне от 17 500 000 до 20 500 000 из них подходящие только нечетные. Нет смысла перебирать все числа, достаточно взять только нечетные из диапазоона и посмотреть к каким числам они подходят. При 3 диапазон будет от 11 666 666 до 13 333 333 из них подходящие опять же только нечетные и само 3 ну и т д…
Хотя тогда придеться хранить словарь с каждым числов в виде ключа и значением нечетных делителей, так что ХЗ.
А считать оно буде по любому долго, потому что под условие задачи попадает в среднем каждое 3-е число. Тоесь для каждого третьего числа нужно перебрать все делители, если не найти какйто простой способ понять сколько у числа нечетных делителей, по типу “если сумма всех цифр равна …..”



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Апрель 22, 2021 11:24:05)

Офлайн

#9 Апрель 22, 2021 21:10:58

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9740
Репутация: +  843  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

Нашёл тут у него условие дополнительное

Lee
Заранее спасибо.(1 и само число не считать).
Так что единицу и само число не считаем, либо вводим, что не меньше пяти делителей, а меньше семи делителей.

PEHDOM
наверное да, но вот как? тут слишком много чисел попадает под условия задачи. и какого общего признака я у них не вижу
Я думаю, там есть какой-то период внутри последовательности, через который её можно сократить по количеству элементов, для которых уже можно применять любой лобовой алгоритм. Ну, типа как у синуса, который простирается от минус бесконечности до плюс бесконечности на оси абсцисс, но всегда можно сказать, чему равно его значение на миллиардных значениях абсцисс, так как функция периодическая и у неё везде всё повторяется.



Офлайн

#10 Апрель 23, 2021 12:53:01

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Задача из егэ по информатике

py.user.next
Я думаю, там есть какой-то период внутри последовательности,
Может и есть но вот так явно его не видно.
Внезапно алгоримт от обратного работает сносно, считает 5 миллионов около 25-30 секунд, и еще столько же потом печатает. При том что особо не заморачивался, если заморочится, можно еще секунду-другую выиграть. Все 5 миллионов не сверял, может гдето какайто косяк и вылезет но первые и последние 100 сходятся с грубым перебором (при условии что 1 и само число не считать).
 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)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version