IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Делители произведения, (олимпиадная задача)
Айра
сообщение 11.12.2006 20:58
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


Зональная олимпиада по информатике.
Задача 2. "делители произведения"(20 баллов)
Задано N натуральных чисел a1,a2,...,aN (1<=N<=20), каждое из которых находится в интервале от 1 до 10000.
Необходимо определить количество натуральных делителей произведения a1*a2*...*aN.
Требуется написать программу, которая вычисляет количество натуральных делителей произведения вышеназванного числа.
Входные данные
Натуральное число N. Числа a1,a2,...,aN, записанные через пробел.
Выходные данные
Число натуральных делителей
Пример:
Вход:
4
3 5 7 720
Выход:
120

Мое решение:

program z2(input,output);
uses wincrt;
label m1;
var k,n: integer;
p,i: longint;
a: array[1..10000] of integer;
begin
p:=1;
k:=0;
m1: writeln ('введите количество чисел');
readln (n);
if (n<=0) or (n>=21) then
begin
writeln ('число должно быть в интервале от 1 до 20');
goto m1;
end;
writeln ('введите значения чисел');
for i:=1 to n do
begin
read (a[i]);
p:=p*a[i];
end;
for i:=1 to p do
begin
if p mod i=0 then k:=k+1;
end;
writeln (k);
end.



Если что, не судите строго. Я не волшебник, а только учусь. rolleyes.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Malice
сообщение 11.12.2006 21:23
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Цитата(Айра @ 11.12.2006 20:58) *

Мое решение:
, не судите строго. Я не волшебник, а только учусь. rolleyes.gif

Произведение 20 чисел от 1 до 10к это еденица с 80-тью нулями, что точно не влезет в longint smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Айра
сообщение 11.12.2006 23:41
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


В этом проблема, а типа с большим диапазоном нет (по крайней мере в моей книге). Может там какое-то другое решение... smile.gif

М
Обсуждение продолжается здесь, когда оно закончится - в теме "Олимпиадные Задачи" появится ссылка на этот топик...

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Malice
сообщение 12.12.2006 0:20
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Цитата(Айра @ 11.12.2006 23:41) *

В этом проблема, а типа с большим диапазоном нет (по крайней мере в моей книге). Может там какое-то другое решение... smile.gif

Такие задачи в лоб не решаются, это ж очевидно. Раз мы не можем записать такое число, то можно представить его в виде произведения простых множителей (сперва разложить сами числа и сложить их степени), а уж оттуда должно получится искомое число..
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Malice
сообщение 13.12.2006 17:33
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Вот где-то так получилось:

const n=4;
const a:array [1..n] of longint= (3,5,7,720);
var i,j,k,l,z:longint;
b:boolean;
begin
k:=1;
z:=a[1];
for i:=2 to n do if a[i]>z then z:=a[i];
for i:=2 to round(sqrt(z)) do begin
b:=false;
for j:=2 to i-1 do b:=b or (i mod j=0);
if not(b) then begin
z:=0;
for j:=1 to n do begin
l:=i;
while (a[j] mod l)=0 do begin l:=l*i; inc(z); end;
end;
k:=k*(z+1);
end; end;
writeln (k);
end.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Michael_Rybak
сообщение 13.12.2006 18:11
Сообщение #6


Michael_Rybak
*****

Группа: Модераторы
Сообщений: 1 046
Пол: Мужской
Реальное имя: Michael_Rybak

Репутация: -  32  +


А можно без проверки на простоту (только если массив не константный):

...
k := 1;
for i := 2 to 10000 do begin
z := 0;
for j := 1 to n do
while a[j] mod i = 0 do begin
a[j] := a[j] div i;
Inc(z);
end;
k := k * (z + 1);
end;
...


Только вот лонгинта не всегда будет хватать smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Айра
сообщение 15.12.2006 15:01
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


В принципе, я поняла как надо было делать. Спасибо всем! smile.gif
Только вот что такое round:
Цитата
for i:=2 to round(sqrt(z)) do unsure.gif


Сообщение отредактировано: Айра - 15.12.2006 15:02
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Malice
сообщение 15.12.2006 15:04
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Округление до целого типа.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Айра
сообщение 15.12.2006 20:29
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


Еще раз спасибо! Теперь мне все ясно, как и то, что на олимпиаде мне делать было нечего. smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 18.07.2025 13:55
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"