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

Delphi Sources



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

Закрытая тема
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.01.2013, 18:07
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
Восклицание Задача о нахождении простых чисел, pascal

Вот такую задачу мне следует выполнить:

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


Технические условия
Входные данные

В первой строке находится количество тестовых случаев T (0 ≤ T ≤ 1049), а далее в T отдельных строках по одному числу – номер очередного подсмотренного билета N (0 ≤ N ≤ 4·109).

Выходные данные

Для каждого тестового случая в отдельной строке вывести номер предполагаемого счастливого лотерейного билета без ведущих нулей.


Информация о задаче
Лимит времени: 1 секунда
Лимит памяти: 64 MB
Баллы за пройденный тест: 4.54545
Источник: II Открытая Дистанционная Олимпиада 2012-2013 им. В.Л.Дидковского
Мои результаты: 0/2

Пример:
Пример входных данных
3
6
20
100

Пример выходных данных
7
23
101
================================================== ========

Сразу стало ясно, что о решетах Эратосфена и Аткина можно забыть.
Но как я ни бился, ничего не получается!
Первая моя реализация: olymp_lotery_v1.zip
Использовалась база простых чисел до sqrt(2*10^9)
Код оказался слишком большим, так что система отказалась принять его

Вторая реализация медленней, воркабельна, но система проверки выдала мне 80% неправильных ответов. Остальные 20% пришлись на истечение лимита времени выполнения программы.
Вот эта реализация: olymp_lotery_v2.zip


Как же быть? На С++ почти не пишу.
  #2  
Старый 12.01.2013, 18:18
Аватар для 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
Репутация: выкл
По умолчанию

Опять наркоманские олимпиадные задачи.

Опубликуй код, не хочется в архивах рыться.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
  #3  
Старый 12.01.2013, 18:26
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
По умолчанию

Цитата:
Опять наркоманские олимпиадные задачи.

Опубликуй код, не хочется в архивах рыться.

Первая версия уж очень велика для публикации, да и надеятся на неё без толку, размер кода не катит.

Вот, реализация второй версии:

Код:
program olymp_lotery;

function isSimple(X: cardinal): boolean;
var i: cardinal;
Begin
     result:=false;
     if x<2 then Exit;
     if not odd(x) and (x<>2)
          then exit;
     i:=3;
     while i <= sqrt(x) do
     begin
          if x mod i = 0 then Exit;
          inc(i,2);
     end;
     result:=true;
End;

var
N,i,T:cardinal;
begin
readln(T);
while t<>0 do
begin inc(n);
readln(n);
i:=N;
while (n-i)<100 do
begin
if isSimple(N) then break;
inc(N,1);
end;
writeln(N);
dec(t);
end;
end.

Последний раз редактировалось D_E_N_, 12.01.2013 в 18:33.
  #4  
Старый 12.01.2013, 21:57
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Во-первых, для скорости sqrt(x) лучше посчитать один раз и сохранить, потом везде вызывать.
Во-вторых, в основной программе
Код:
inc(n);
readln(n);
Как-то бессмысленно.
В-третьих, если убрать вызов функции (записать ее код прямо в цикле), то несколько ускорится.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
  #5  
Старый 12.01.2013, 22:27
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
По умолчанию

по скорости почти всё проходит, не проходит по правильности выдачи результатов

Цитата:
Во-вторых, в основной программе
Код:
inc(n);
readln(n);

это я виноват: inc(n) осталось с тех пор, когда я автоматизировал ввод, чтоб по 100 раз не вводить одни и те же числа

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

А чтение точно с консоли? Обычно автопроверялки берут из файла.

З.Ы. И в-четвертых, завязывай с олимпиадными задачками.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
  #7  
Старый 12.01.2013, 23:18
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
По умолчанию

Цитата:
Сообщение от Bargest
А чтение точно с консоли? Обычно автопроверялки берут из файла.

З.Ы. И в-четвертых, завязывай с олимпиадными задачками.

чтение точно с консоли. завязать рад, но сейчас эту надо 100% решить...
кстати, вот ссылка на неё: http://www.e-olimp.com.ua/problems/3608
  #8  
Старый 12.01.2013, 23:30
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Возможно ему не нравится, что результат выводится сразу. Торт знает эти автопроверки.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
  #9  
Старый 13.01.2013, 00:14
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
По умолчанию

Вот собрал новую, среди 20-ти тестов стал проходить первый. По времени всё укладывается. Здесь я решил работать с файлами. Для читабельности сделал двумя функциями.

Код:
program zbs;

function IsSimple(p: cardinal): Boolean;
var
i, k : cardinal;
begin
IsSimple := True;
if (p = 0) or (p = 1) then IsSimple := False;
k := Trunc(Sqrt(p));
for i:=2 to k do
if p mod i = 0 then begin
IsSimple := False;
Break;
end;
end;

function next(num:cardinal):cardinal;
var
n:cardinal;
begin
n:=num;
if n<=2 then begin result:=2; exit; end;
inc(n);
if n or 1 <> n then inc(n);
while (n-num)<200 do
begin
if issimple(n) then break;
inc(n,2);
end;
result:=n;
end;

var
f:text;
T,i:word;
p:array[1..1049]of cardinal;
begin
assign(f,'input.txt');
reset(f);
readln(f,T);
for i:=1 to T do
readln(f,p[i]);
close(f);


for i:=1 to T do
begin
p[i]:=next(p[i]);
end;

assign(f,'output.txt');
rewrite(f);
for i:=1 to T do
writeln(f,p[i]);
close(f);
end.
  #10  
Старый 13.01.2013, 23:52
Аватар для D_E_N_
D_E_N_ D_E_N_ вне форума
Прохожий
 
Регистрация: 27.06.2012
Сообщения: 15
Репутация: 10
По умолчанию

Всё, решил! Можно закрывать тему! Пришлось лишь слегка модифицировать данный пример:

Код:
program zbs;

function IsSimple(p: cardinal): Boolean;
const
base:array[1..54]of byte=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251);
var
i, k : cardinal;  pff:boolean;
begin
IsSimple := True;
k := Trunc(Sqrt(p));
i:=1; pff:=true;
while i<55 do
begin
if p mod base[i] = 0 then begin
if p<>base[i] then
begin
IsSimple := False; pff:=false;
end;
Break;
end;
inc(i);
end;
if pff=true then
begin
i:=base[i];
while i<k do
 begin
  if p mod i = 0 then begin
   IsSimple := False;
   Break;
  end;
  inc(i,2);
 end;
end;

end;

function next(num:cardinal):cardinal;
var
n:cardinal;
begin
n:=num;
if n<2 then begin result:=2; exit; end;
inc(n);
if n or 1 <> n then inc(n);
while true do
begin
if issimple(n) then break;
inc(n,2);
end;
result:=n;
end;

var
f:text;
T,i:word;
p:array[1..1049]of cardinal;
begin
assign(f,'input.txt');
reset(f);
readln(f,T);
for i:=1 to T do
readln(f,p[i]);
close(f);


for i:=1 to T do
begin
p[i]:=next(p[i]);
end;

assign(f,'output.txt');
rewrite(f);
for i:=1 to T do
writeln(f,p[i]);
close(f);
end.
  #11  
Старый 14.01.2013, 00:12
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Тему закрывает тот, кто её открыл.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
OTVET (14.01.2013)
Закрытая тема


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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