ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила

Как писать решения на Паскале

Программы на Паскале компилируются на сервере с помощью 32-битного компилятора FreePascal 2.6.4. Он настроен в режиме совместимости с Borland Delphi и запускается со следующими параметрами:

ppc386 %1 -WC -Ci-o-r-t- -Xs -Sdgich -Se10 -l- -vwnh -n -dONLINE_JUDGE

Вы можете скачать FreePascal и прочитать online документацию на сайте www.freepascal.org.

Пример решения задачи

Вот пример решения задачи A + B на Паскале:

var
   a, b: integer;
begin
   readln(a, b);
   writeln(a + b);
end.

Что нового в 32-битном компиляторе по сравнению с 16-битным

Если вы привыкли писать программы в старых 16-битных компиляторах для DOS, например, в Borland Pascal 7.0, то вам будет полезно знать следующее:

  • Можно использовать массивы размером более 64 КБ.
  • Тип integer является 32-битным и совпадает с типом longint. 16-битный целый знаковый тип называется smallint.
  • Строки теперь не ограничены 255 символами. Не следует обращаться к нулевому символу, чтобы узнать длину строки, используйте для этого функцию length(s). Установить длину строки можно при помощи процедуры setlength(s, n).

Кроме того, появилось много новых ключевых слов. Следующие слова не могут быть переопределены или использованы как идентификаторы:

as               false                new
class            finalization         on
dispose          finally              property
except           initialization       raise
exit             is                   true
exports          library              try

В дополнение к указанным выше, слова protected и published стали зарезервированными внутри описания объекта. Также имя result в теле функции зарезервировано: значением соответствующей переменной является результат работы функции, и объявление второго такого имени приведёт к ошибке компиляции. Например, следующие определения функций эквивалентны:

function Sum(a, b: integer): integer;
begin
   Sum := a + b;
end;

function Sum(a, b: integer): integer;
begin
   result := a + b;
end;

А вот такой код не скомпилируется:

function Sum(a, b: integer): integer;
var
   result: integer;
begin
   result := a + b;
   Sum := result;
end;

Особенности компилятора по сравнению с другими 32-битными компиляторами Паскаля

Есть некоторые особенности компилятора, используемого на сервере, которые полезно знать.

  • На сервере нет модулей crt и wincrt, так как процедуры, содержащиеся в них, не нужны для решения задач.
  • При динамическом выделении памяти размер блока округляется до кратного 16 байтам. Например, если вы выделяете много блоков по 4 байта, то ваша программа будет использовать в 4 раза больше памяти, чем надо. Пользуйтесь статическими структурами данных, они лишены этого недостатка и, как правило, работают быстрее динамических.
  • Множества могут занимать лишь 4 или 32 байта, что также может привести к значительному перерасходу памяти. Часто хорошей альтернативой множествам оказывается использование битов целого числа (или массива целых чисел).
  • Нельзя явно приводить типы переменных целочисленного типа и типа с плавающей точкой. Выражение «x := extended(i)», где x имеет тип extended, а i — integer, является ошибочным. Тогда как выражение «x := i» — правильное.

Нельзя менять значение переменной цикла for внутри цикла. Следующий код не скомпилируется:

for i := 1 to 10 do
begin
   if i mod 2 = 0 then inc(i);
   writeln(i);
end;

Более того, после цикла for значение переменной цикла не определено. Т.е. ее значение нельзя использовать, например, в целях поиска. Следующий пример сработает по-разному на разных компиляторах:

var
   a: array[1..10] of integer;
   i: integer;
begin
   for i:=1 to 10 do
      a[i] := i*i;
   for i:=1 to 10 do
      if a[i] = 17 then break;
   writeln('i = ', i);
end.
{
   Delphi output:      i = 11
   FreePascal output:  i = 10
}

Как пользоваться 64-битными целыми типами данных

Компилятор полностью поддерживает 64-битные целые, как со знаком, так и без знака. 64-битное целое со знаком имеет диапазон значений от –9223372036854775808 до 9223372036854775807, без знака — от 0 до 18446744073709551615. Знаковый тип назывется int64, беззнаковый — qword. Следующий пример иллюстрирует использование 64-битных целых типов:

var
   a: int64;
   b: qword;
begin
   read(a);
   read(b);
   writeln(a);
   writeln(b);
end.

Как считать данные до конца входного потока

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

{numbers}
var n: integer;
...
while not seekeof do
begin
   read(n);
   ...
end;

{lines}
var line: string;
...
while not eof do
begin
   readln(line);
   ...
end;

{characters}
var c: char;
...
while not eof do
begin
   read(с);
   ...
end;

Прочие замечания

Иногда вердикт Wrong Answer на самом деле означает Runtime error. Это связано с тем, что FreePascal самостоятельно перехватывает некоторые ошибки выполнения программ и выводит сообщение в выходной поток.

Для того, чтобы увеличить объем стека и избежать его переполнения при использовании «глубокой» рекурсии, следует использовать специальную директиву (в примере размер стека устанавливается равным 16 МБ):

{$M 16777216}

Удобно использовать для отладки решений условную директиву ONLINE_JUDGE:

var
   a, b: longint;
begin
{$IFNDEF ONLINE_JUDGE}
   assign(input, 'input.txt');
   reset(input);
   assign(output, 'output.txt');
   rewrite(output);
{$ENDIF}
   readln(a, b);
   writeln(a + b);
{$IFNDEF ONLINE_JUDGE}
   close(input);
   close(output);
{$ENDIF}
end.

Такая программа на вашем компьютере будет читать данные из файла input.txt и выводить результат в файл output.txt. На сервере же она будет пользоваться стандартными входным и выходным потоками.

Прежние компиляторы

  • FreePascal 1.0.6 использовался до 8 августа 2005 года.
  • FreePascal 2.0.1 использовался до 4 января 2006 года.
  • FreePascal 2.0.2 использовался до 24 октября 2006 года.
  • FreePascal 2.0.4 использовался до 3 октября 2014 года.