Открытая олимпиада по программированию

www.olympiads.ru

Новости
Информация об олимпиаде
График проведения и правила отбора
Заключительный этап
Правила проведения заключительного этапа
Итоговые результаты
Материалы олимпиады
Работы победителей и призёров
Заочный этап
Условия задач
Результаты длинного тура
Результаты короткого тура
Архив длинного тура
Архив короткого тура
Контактная информация

Генеральный спонсор олимпиады
фирма 1С

Олимпиада проводится при поддержке
ЦРИТО МФТИ

и компании Яндекс

Партнёром олимпиады является
платформа Codeforces.com

Олимпиады прошлых лет
2020/21
2019/20
2018/19
2017/18
2016/17
2015/16
2014/15
2013/14
2012/13
2011/12
2010/11
2009/10
2008/09
2007/08
2006/07

XII Открытая олимпиада школьников по программированию, 2017/18 учебный год

Допустимые языки программирования и ввод-вывод

Решения участников проверяются на компьютере с операционной системой Linux. Используются 32-битные версии языков программирования. Для проверки языка Basic используется компилятор Free Basic, который доступен в двух вариантах: стандартном 32-битном и 16-битном с поддержкой синтаксиса qbasic. Иные языки программирования не предполагаются.

Для проверки решений участников олимпиады жюри использует следующие компиляторы (интерпретаторы):

Обозначение Название, версия Ключи компиляции (итерпретации)
dcc Borland Delphi 6 (Kylix) 14.5 -Q
fpc-32 Free Pascal 2.6.2  
gcc-32 GNU C 5.2.0 -O2 --std=gnu11 -m32 -lm
g++-32 GNU C++ 5.2.0 -O2 --std=gnu++11 -m32 -lm
clang-32 clang C 3.7 -m32 -Wall -O2 -std=gnu99 -lm
clang++-32 clang C++ 3.7 -m32 -Wall -O2 -lm
javac Java JDK 1.8.0_66  
javac7 Java JDK 7 1.7.0_80  
python Python 2.7.3 -W ignore
python3 Python 3.4.3 -W ignore
php PHP 5.4.17 -n
perl Perl 5.14.4 -W
fbc Free Basic 0.90.1, совместимый с qbasic -lang qb
fbc-32 Free Basic (32 bit) 0.90.1  

Эталонные решения задач подготовлены, как правило, с использованием компилятора g++-32. Жюри гарантирует, что все задачи могут быть решены при помощи g++-32 и не гарантирует возможности полного решения всех задач с использованием других языков программирования. Особенно это относится к таким языкам, как Python, Perl, PHP, Basic.

Программа должна читать входные данные со стандартного ввода и выводить результат на стандартный вывод. Альтернативно программа может читать данные из файла input.txt и выводить результат в файл output.txt.

Программа на любом языке программирования должна завершаться с кодом возврата 0. В частности, программа на C всегда должна заканчиваться оператором return 0;

Программы на языке Python могут содержать только символы ASCII, то есть недопустимо использование символов, чьи коды превышают 127, в частности, недопустимо использование комментариев на русском языке.

Ниже приведены замечания по разным языкам программирования и приведен пример программы, вычисляющую сумму двух целых чисел, с использованием файлового ввода-вывода.


Pascal, Delphi

Примечание для программирующих на Delphi: Имена стандартных модулей пишутся точно так же, как в документации (имеется в виду сочетание больших и маленьких букв) и только так. Например: Math, SysUtils.

var a,b:longint;
begin
    assign(input,'input.txt');
    reset(input);
    assign(output,'output.txt');
    rewrite(output);
    read(a,b);
    writeln(a+b);
    close(input);
    close(output);
end.

C

#include <stdio.h>

int main(void)
{
  long a, b;
  FILE *fin, *fout;
  fin = fopen("input.txt", "r");
  fout = fopen("output.txt", "w");
  fscanf(fin, "%ld%ld", &a, &b);
  fprintf(fout, "%ld", a + b);
  fclose(fin);
  fclose(fout);
  return 0;
}

Примечание для программирующих на GNU C/C++: При выводе значений переменных типа long long под ОС Windows нужно использовать спецификатор %I64d, а при сдаче решений на проверку (для ОС Linux) - спецификатор %lld. "Универсальный" код, который работает правильно под обеими системами, может выглядеть так:

#ifdef WIN32
	printf("%I64d\n",ans);
#else
	printf("%lld\n",ans);
#endif

C++

#include <fstream>

using namespace std;

int main ()
{
  long a, b;
  ifstream fin ("input.txt");
  ofstream fout ("output.txt");
  fin >> a >> b;
  fout << a + b << endl;
  fin.close ();
  fout.close ();
  return 0;
}

Java

Программа должна находиться в единственном классе с именем Main (обязательно с большой буквы), метод main должен находиться внутри класса Main. Вложенные классы допускаются.

import java.io.*;
public class Main
{
   public static void main(String[] args) throws Exception
   {
	StreamTokenizer in = new StreamTokenizer(
          new BufferedInputStream(
              new FileInputStream(new File("input.txt"))));
	PrintStream out = new PrintStream(new File("output.txt"));
		
	int a, b;
	in.nextToken(); a = (int) in.nval;
	in.nextToken(); b = (int) in.nval;
	out.println(a + b);
   }
}

QBasic (FreeBasic с ключом -lang qb)

open "input.txt" for input as #1
open "output.txt" for output as #2
input #1, a, b
print #2,a + b
close #1
close #2

perl, php, python

В скриптовых языках perl, php, python, ruby отсутствует возможность потокового ввода данных, свойственного для языков Pascal, C и C++, то есть в этих языках нельзя простыми методами считать из входного файла последовательность целых чисел (действительных чисел, строк и т.д.), если неизвестно, находятся ли эти числа в одной строке или в разных строках.

Для ввода данных в этих языках предлагается считывать содержимое всего файла сразу в строковую переменную, а затем использовать стандартную функцию split для разбивки этой переменной на поля. Функция split игнорирует все начальные и конечные пробельные символы (то есть пробелы, символы табуляции и символы новой строки), а все прочие символы разбиваются на последовательности, состоящие из непробельных символов, пробельные символы являются разделителями для полученных последовательностей. В результате получается список, состоящий из строк непробельных символов, содержащихся в исходном файле. Например, если в исходном файле записана строка "1 2 abc" (количество пробелов неважно), то в полученном списке будет три элемента - "1", "2" и "abc".

В языке php имеется небольшое отличие - функция называется preg_split, при ее вызове в качестве аргумента необходимо явно указать регулярное выражение, которое задает разделитель полей (это /\s+/, в языках perl, python и ruby такое значение разделителя используется по умолчанию), и перед вызовом функции preg_split необходимо явно удалить начальные и концевые пробелы из строки функцией trim (в языках perl, python и ruby это делает сама функция split).

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

Ниже приведены примеры решения задачи "A+B" на языках perl, php, python.


perl

#!/usr/bin/perl -w

# Объявляем файлы FIN и FOUT для ввода-вывода данных
open(FIN, "<input.txt");
open(FOUT,">output.txt");

# В переменной $/ записан символ, который считается разделителем строк
# Удаление этой переменной приведет к тому, что весь файл будет считаться
# одной большой строкой.
undef $/;

# Считываем содержимое всего файла в переменную $_
$_=<FIN>;

# Разбиваем переменную $_ на поля по пробельным символам
# и записываем поля в список @InputData
my @InputData=split;

# Теперь в элементах списка $InputData[0] и $InputData[1]
# записаны два входных числа. Запишем их сумму в переменную $Answer
my $Answer=$InputData[0]+$InputData[1];

# Выведем результат в файл
print FOUT $Answer;

# Закроем файлы FIN и FOUT
close(FIN);
close(FOUT);

php

<?php
# Считываем весь файл при помощи функции file_get_contents,
# удаляем начальные и конечные пробелы при помощи функции trim
# результат разбиваем на поля функцией split по шаблону /\s+/,
# задающему последовательность пробельных символов в качестве разделителя
# и записываем результат в массив InputData
$InputData=preg_split('/\s+/', trim(file_get_contents('input.txt')));

# Теперь в элементах массива $InputData[0] и $InputData[1]
# записаны два входных числа.
# Запишем их сумму в переменную $Answer
$Answer=$InputData[0]+$InputData[1];

# Объявляем файл FOUT для вывода данных
$FOUT=fopen("output.txt","w");

# Выведем результат в файл FOUT 
fputs($FOUT,$Answer);

# Закроем файл FOUT
fclose($FOUT);

?>

python

#!/usr/bin/python

# Объявляем файлы FIN и FOUT для ввода-вывода данных
FIN  = open("input.txt",  "r")
FOUT = open("output.txt", "w")

# Считываем весь файл при помощи метода read(),
# результат разбиваем на поля по пробельным символам методом split()
# и записываем в список InputData
InputData = FIN.read().split()

# Теперь в элементах списка InputData[0] и InputData[1]
# записаны два входных числа в виде строк.
# Преобразуем их к типу int и запишем их сумму в переменную Answer
Answer = int(InputData[0]) + int(InputData[1])

# Выведем результат в файл
print >> FOUT, Answer

# Закроем файлы FIN и FOUT
FIN.close()
FOUT.close()


python 3

#!/usr/bin/python3

# Объявляем файлы FIN и FOUT для ввода-вывода данных
FIN  = open("input.txt",  "r")
FOUT = open("output.txt", "w")

# Считываем весь файл при помощи метода read(),
# результат разбиваем на поля по пробельным символам методом split()
# и записываем в список InputData
InputData = FIN.readline().split()

# Теперь в элементах списка InputData[0] и InputData[1]
# записаны два входных числа в виде строк.
# Преобразуем их к типу int и запишем их сумму в переменную Answer
Answer = int(InputData[0]) + int(InputData[1])

# Выведем результат в файл
print(Answer, file = FOUT)

# Закроем файлы FIN и FOUT
FIN.close()
FOUT.close()