Найдите все натуральные числа, принадлежащие отрезку [35 000 000; 40 000 000], у которых ровно пять различных нечётных делителей (количество чётных делителей может быть любым). В ответе перечислите найденные числа в порядке возрастания.
Ответ:
Решим задачу перебором. Находя очередной делитель числа, будем проверять, является ли этот делитель нечётным, и, если является, будем прибавлять
Приведём решение на языке Pascal.
var
count, i, j, k, sqrtI: longint;
begin
for i := 35000000 to 40000000 do begin
count := 0;
sqrtI := round(sqrt(i));
for j := 1 to sqrtI do begin
if i mod j = 0 then begin
if j mod 2 = 1 then count := count + 1;
k := i div j;
if k mod 2 = 1 then begin
count:=count + 1;
if j = k then count:=count - 1;
end;
end;
if count > 5 then break;
end;
if count = 5 then writeln(i);
end;
end.
В результате работы программа должна вывести следующее:
35819648
38950081
39037448
39337984
Приведем другое решение.
Число имеет ровно пять нечетных делителей, если оно имеет вид 2n · p4, где p — простое число, n — произвольное натуральное число. В этом случае нечетными делителями числа будут числа 1, p, p2, p3 и p4. Следовательно, можно искать корень четвертой степени из числа, деленного на максимально возможную степень двойки. Если этот корень четвертой степени является простым числом, то само число имеет ровно пять нечетных делителей.
Приведем программу на языке Pascal, реализующую этот способ.
var
simple, i, j, c, sqrtI: longint;
begin
for i := 35000000 to 40000000 do begin
c:=i;
while c mod 2 = 0 do begin
c:=c div 2;
end;
sqrtI := round(sqrt(c));
sqrtI:= round(sqrt(sqrtI));
if sqrtI * sqrtI * sqrtI * sqrtI = c then begin
simple:=1;
for j:=3 to round(sqrt(sqrtI)) do begin
if sqrtI mod j=0 then begin
simple:=0;
break;
end;
end;
if simple=1 then writeln(i);
end;
end;
end.
Приведем математическое обоснование данного способа.
Пусть разложение числа m на простые множители имеет вид тогда количество делителей
В частности, четное число раскладывается на множители как
где множители ai — нечетные числа. Тогда число имеет
четных делителей и
нечетных.
По условию задачи требуется, чтобы число имело
Примечание Никиты Степанова.
Второй способ решения будет давать неверный результат, если в заданном диапазоне есть число, являющееся степенью двойки. В этом случае получим sqrtI = c = 1, цикл проверки делимости числа не выполнится ни разу, и переменная simple останется
Приведём решение Владимира Лукьянчикова на языке Pascal.
uses school;
for var i := 35000000 to 40000000 do
if i.Divisors.Where(x -> x mod 2 = 1).Count = 5 then println(i);
Приведём решение Сергея Фефелова на языке Python.
def isPrime(n):
r = n%2 + 1
for i in range(r+1, int(n**0.5)+1, r):
if n % i==0: return False
return True
start, end = 35_000_000, 40_000_000
for i in range(start, end+1):
n = i
while n%2 == 0: n //= 2
q = round(n**0.25)
if n == q**4 and isPrime(q):
print(i)
Приведём решение Юрия Красильникова на языке Python.
def prime(n):
k = 2
while k**2 <= n:
if n%k == 0:
return False
k += 1
return True
bot,top = 35000000,40000000
mp = int(top**0.25)+3
m2 = len(bin(top))
nums = [p**4*2**m for p in range(3,mp,2) for m in range(m2) if prime(p) and bot <= p**4*2**m <= top]
for n in sorted(nums):
print(n)

