Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.10.2012, 21:14
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию Ускорить выполнение

Здравствуйте! Обращаюсь к знатокам. Есть задача "По заданному натуральному числу N необходимо вычислить количество натуральных чисел, которые являются делителями N! (факториала числа N)."
Доп. условие: лимит времени 1с.
Но у меня не проходит несколько тестов из-за исчерпанного лимита времени. Как можно оптимизировать?
Код:
var fack:Int64;
 i,n,k:Integer;
 begin
 fack:=1;
 Readln(n);
for i:=2 to n do
 fack:=fack*i;

for i:=1 to fack do
if fack mod i=0 then inc(k);
 Writeln(k);
 end.

Последний раз редактировалось Dmitry_DM, 21.10.2012 в 21:21.
Ответить с цитированием
  #2  
Старый 21.10.2012, 21:46
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Код:
var fack:Int64;
 i,n,k:Integer;
 begin
 fack:=1;
 Readln(n);
asm
  cli
end
for i:=2 to n do
 fack:=fack*i;
 
for i:=1 to fack do
if fack mod i=0 then inc(k);
asm
  sti
end
 Writeln(k);
 end.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 21.10.2012, 22:05
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Код:
var fack:Int64;
 i,n,k:Integer;
 begin
 fack:=1;
 Readln(n);
asm
  cli
end
for i:=2 to n do
 fack:=fack*i;
 
for i:=1 to fack do
if fack mod i=0 then inc(k);
asm
  sti
end
 Writeln(k);
 end.
А это вообще на delphi Consol Application работает? У меня пишет, что странный код:
Код:
asm
и запускается только если добавить ; после end здесь
Код:
asm
  cli
end
что это?
Код:
cli
Код:
sti
Но при выполнении что-то очень быстро выдает, но не ответ.

Последний раз редактировалось Dmitry_DM, 21.10.2012 в 22:11.
Ответить с цитированием
  #4  
Старый 21.10.2012, 22:10
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

M.A.D.M.A.N., а не наоборот?

Dmitry_DM, во втором цикле достаточно to fack div 2 do
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #5  
Старый 21.10.2012, 22:12
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
Радость

Цитата:
Сообщение от Aristarh Dark
M.A.D.M.A.N., а не наоборот?
Именно в такой последовательности "Clear Interrupt-Enable Flag" и "Set Interrupt-Enable Flag".

В принципе второй цикл можно затолкать в первый.

Типа:
Код:
var fack:Int64;
 i, j,n,k:Integer;
 begin
 fack:=1;
 Readln(n);
for i:=2 to n do
begin
 for j := fack to fack * i do
  inc(k, integer(fack mod j=0));
 fack:=fack*i;
end;

 Writeln(k);
 end.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 21.10.2012 в 22:17.
Ответить с цитированием
  #6  
Старый 21.10.2012, 22:16
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Хм... А я почему-то думал, что именно когда флаг установлен прерывания игнорируются. Хотя, имхо, винде все эти "фигли-мигли" пофиг.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #7  
Старый 21.10.2012, 22:16
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Именно в такой последовательности "Clear Interrupt-Enable Flag" и "Set Interrupt-Enable Flag".
Под виндой не желательно делать ни то, ни другое. По-хорошему винда не даст юзать cli. Слишком опасно. Вроде выдается что-то типа Privileged instruction.
А вот под досом - вполне.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #8  
Старый 21.10.2012, 22:19
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Вроде выдается что-то типа Privileged instruction.
Причем эта проверка выполняется самим процессором. Т.е. по сути если дескриптору (descriptor privilege level) назначить нужный уровень (0), то работать будет
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 21.10.2012 в 22:22.
Ответить с цитированием
  #9  
Старый 21.10.2012, 22:22
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Именно в такой последовательности "Clear Interrupt-Enable Flag" и "Set Interrupt-Enable Flag".

В принципе второй цикл можно затолкать в первый.

Типа:
Код:
var fack:Int64;
 i, j,n,k:Integer;
 begin
 fack:=1;
 Readln(n);
for i:=2 to n do
begin
 for j := fack to fack * i do
  inc(k, integer(fack mod j=0));
 fack:=fack*i;
end;

 Writeln(k);
 end.
Есть тесты: ввод 4 вывод 8
А по вашему коду ввод 4 вывод 76808195

Последний раз редактировалось Dmitry_DM, 21.10.2012 в 22:25.
Ответить с цитированием
  #10  
Старый 21.10.2012, 22:28
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Туплю чето.
I II III IV V VI VII VIII IX X
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #11  
Старый 21.10.2012, 22:41
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Сокращаем количество проходов в 2 раза:
Код:
var
  i,fack: Int64;
  n,k: Integer;
begin
  fack:=1;
  Readln(n);
  for k:=2 to n do
    fack:=fack*k;
  k:=2;
  i:=2;
  while i <= fack div 2 do begin
    if (fack mod i) = 0 then
      inc(k);
    inc(i);
  end;
  Writeln(k);
end.
На больших значениях fack переменная типа integer никогда не доберётся до максимального значения (пример - fack = 14! = 87 178 291 200, Integer = -2 147 483 648..2 147 483 647). I тоже должна быть Int64. Но int64 не работает в циклах for-do, так что извращаемся.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj

Последний раз редактировалось PhoeniX, 21.10.2012 в 23:12.
Ответить с цитированием
Этот пользователь сказал Спасибо PhoeniX за это полезное сообщение:
Dmitry_DM (22.10.2012)
  #12  
Старый 22.10.2012, 06:29
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 663
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Цитата:
Сообщение от Dmitry_DM
"По заданному натуральному числу N необходимо вычислить количество натуральных чисел, которые являются делителями N! (факториала числа N)."
Ребят, вы меня извините, но:
1. Факториа́л числа n (обозначается n!, произносится эн факториа́л) — произведение всех натуральных чисел от 1 до n включительно.
2. Если для некоторого целого числа a и целого числа b существует такое целое число q, что bq=a то говорят, что число a делится нацело на b или что b делит a. При этом число b называется делителем числа a, делимое a будет кратным числа b, а число q называется частным от деления a на b.

Исходя из этого всего возникает вопрос: А зачем вообще считать факториал?
Эта задача - комбинаторная, а не расчетная.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.

Последний раз редактировалось dr. F.I.N., 22.10.2012 в 07:36.
Ответить с цитированием
  #13  
Старый 22.10.2012, 08:10
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Дык задача из разряда прикладных, когда надо сделать нах никому ненужный алгоритм (например коля с васей решили померяться пиписьками, вася снял штаны, а коля побежал в москву, потом в асхтрахань, потом на камчатку, просчитать, сколько пыли было на правом ботинке васи, если известно, что длина пиписьки коли на 1/4 от трети длины четверти квадрата диаметра окружности вписанного в треугольник, угол которого равен углу между яйцами и коленом дяди пети больше на десять в минус четвертой, чем расстояние между луной и плутоном в день летнего солнцестояния в период засухи в африке).

И еще чтоб быстро работало.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #14  
Старый 22.10.2012, 16:15
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Причем эта проверка выполняется самим процессором. Т.е. по сути если дескриптору (descriptor privilege level) назначить нужный уровень (0), то работать будет
Ага, назначь. Вот так запросто. Учитывая, что GDT находится в памяти, которая недоступна для записи простым смертным.
Цитата:
Дык задача из разряда прикладных, когда надо сделать нах никому ненужный алгоритм (например коля с васей решили померяться пиписьками, вася снял штаны, а коля побежал в москву, потом в асхтрахань, потом на камчатку, просчитать, сколько пыли было на правом ботинке васи, если известно, что длина пиписьки коли на 1/4 от трети длины четверти квадрата диаметра окружности вписанного в треугольник, угол которого равен углу между яйцами и коленом дяди пети больше на десять в минус четвертой, чем расстояние между луной и плутоном в день летнего солнцестояния в период засухи в африке).

И еще чтоб быстро работало.
+1.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #15  
Старый 22.10.2012, 16:32
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Вот так запросто.


Пощелкал и готово
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:06.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025