Форум » Обработка целых чисел » №4410 » Ответить

№4410

Caedmil: Здравствуйте можете подсказать в чем заключается ошибка? [pre2] for i in range(520000,550000): b=0 c=0 for a in range(2,i//2): if i%a==0: b+=a c=a if b>10 and str(b)==str(b)[::-1]: print(i,c) [/pre2] Программа выводит: 520211 16781 520874 3802 520993 47363 521482 40114 521653 47423 521947 16837 521978 16838 522060 174020 522077 22699 Ответ у задачи: 520211 16781 520993 47363 521653 47423 521947 16837 522077 22699 Почему у меня появляются лишние значения?

Ответов - 1

leo2601: Доброго времени суток! Ваше решение не учитывает в сумму все делители. Например, максимальный нетривиальный делитель числа 520874 = 260437, на выводе же 3802. Каждый делитель, если не является корнем, имеет парный (обратный) ему делитель. Например: если 8:2 = 4, тогда 8:4 = 2. Таким образом мы можем, опираясь на знание о том, что 8 делится на 2, понять сразу, что 8 делится ещё и на 4. Кроме того, при таком подсчёте следует учитывать корень, который может попасть в сумму дважды. Например: 16:4 = 4, парный делитель тоже = 4. Потому предлагаю такое решение с использованием множества (во избежание того, что некоторые элементы будут учтены несколько раз, см. пример с корнем): k = 0 for i in range(520000,550000): d = set() #множество без повторов for a in range(2,int(i**0.5)+1): #перебор до корня if i%a==0: d |= {a, i//a} #сохраняем прямой и обратный ему делитель if sum(d)>10 and str(sum(d))==str(sum(d))[::-1]: print(i,max(d)) k += 1 if k == 5: break Здесь делители ищем, перебирая до корня, что во много раз эффективнее и быстрее, нежели перебор до половины. Такой перебор позволяет найти все делители. Пример: 36, корень = 6. Тогда делители до корня: 2, 3, 4, 6; обратные им делители - 36:2 = 18, 36:3 = 12; 36:4 = 9; 36:6 = 6. Нашли все делители. И это вместо того, чтобы перебирать до 36//2 = 18.



полная версия страницы