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

Как писать решения на C/C++

Программы на C и C++ компилируются на сервере с помощью компиляторов: Microsoft Visual C++ 2022 17.8, GCC 13.2.0 и Clang 17.0.6. Все компиляторы поддерживают как минимум С17 и С++20. Хороший справочник по современным C и C++: cppreference.com.

Visual C++ 2022 имеет версию, включенную в Visual Studio 2022 v17.8. Компилятор доступен для платформ x86 и x64. Вы можете получить онлайн справочную информацию, а также скачать бесплатную версию Visual Studio Community 2022. Компилятор запускается со следующими параметрами:

// C
cl /TC /MT /EHsc /GL /O2 /W3 /std:clatest /D "ONLINE_JUDGE" %1

// C++
cl /TP /MT /EHsc /GL /O2 /W3 /Za /std:c++latest /D "ONLINE_JUDGE" %1

MinGW GCC 13.2.0 x64 и Clang 17.0.6 x64 взяты из сборки WinLibs. Компиляторы запускаются со следующими параметрами:

// C
gcc -x c -std=c2x -O2 -fno-strict-aliasing -march=native
    -DONLINE_JUDGE -static -Wl,-s,--stack=67108864 -o %1.exe %1

// C++
g++ -x c++ -std=c++23 -O2 -fno-strict-aliasing -march=native
    -DONLINE_JUDGE -static -Wl,-s,--stack=67108864 -o %1.exe %1

// C++
clang++ -x c++ -std=c++23 -O2 -fno-strict-aliasing -march=native
    -DONLINE_JUDGE -static -pthread -Wl,-s,--stack=67108864 -o %1.exe %1

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

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

#include <stdio.h>
int main()
{
   int a, b;
   scanf("%d%d", &a, &b);
   printf("%d\n", a + b);
   return 0;
}

И пример решения той же задачи на языке C++:

#include <iostream>
int main()
{
   int a, b;
   std::cin >> a >> b;
   std::cout << a + b << std::endl;
   return 0;
}

Ввод/вывод

Пример того, как надо пользоваться вводом/выводом, приведен выше. У тех, кто пишет на C++, всегда есть выбор из двух библиотек ввода/вывода — стандартного (scanf, printf) и потокового (cin, cout). Потоковый ввод/вывод удобен в использовании, но работает гораздо медленнее стандартного. Это даже может стать причиной получения вердикта Time limit exceeded. Поэтому, если вы видите, что в задаче надо считывать много входных данных (скажем, больше мегабайта) или много выводить, то не следует использовать потоковый ввод/вывод.

Не забывайте, что функции чтения символов возвращают отрицательные результаты для символов с кодами 128-255. Если во входных данных могут присутствовать такие символы, то лучше явно привести тип считанного символа к unsigned char, чем получить из-за этого вердикты Wrong answer или Runtime error (access violation).

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

#include <stdio.h>
...
// numbers
int n;
while (scanf("%d", &n) != EOF)
{
   ...
}
// lines
char line[1000];
while (gets(line))
{
   ...
}
// characters
int c;
while ((c = getchar()) != EOF)
{
   ...
}
#include <iostream>
...
// numbers
int n;
while (std::cin >> n)
{
   ...
}
// lines
std::string line;
while (std::getline(std::cin, line))
{
   ...
}
// characters
char c;
while (std::cin.get(c))
{
   ...
}

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

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

long long a;
unsigned long long b;

Читать и выводить 64-битные переменные также можно двумя способами в зависимости от используемой библиотеки ввода/вывода:

#include <stdio.h>
...
scanf("%lld", &a);
scanf("%llu", &b);
printf("%lld", a);
printf("%llu", b);

#include <iostream>
...
std::cin >> a;
std::cin >> b;
std::cout << a;
std::cout << b;

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

В решениях задач нельзя кидать исключения (даже внутри блока try … catch) — это будет проинтерпретировано проверяющей системой как Runtime error.

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

#pragma comment(linker, "/STACK:16777216")

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

#include <stdio.h>
int main()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "rt", stdin);
   freopen("output.txt", "wt", stdout);
#endif
   int a, b;
   scanf("%d%d", &a, &b);
   printf("%d\n", a + b);
   return 0;
}

Обратите внимание на то, что функцию freopen можно применять и при использовании потокового ввода/вывода:

#include <iostream>
int main()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "rt", stdin);
   freopen("output.txt", "wt", stdout);
#endif
   int a, b;
   std::cin >> a >> b;
   std::cout << a + b << std::endl;
   return 0;
}

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

  • Intel C++ Compiler 7.0 использовался до 3 августа 2010 года.
  • MinGW GCC 4.7.2 использовался до 3 октября 2014 года.
  • Microsoft Visual C++ 2010 использовался до 22 сентября 2015 года.
  • Microsoft Visual C++ 2013 использовался до 1 сентября 2017 года.
  • MinGW GCC 4.9.1 использовался до 1 сентября 2017 года.
  • Clang 3.5 использовался до 1 сентября 2017 года.
  • Microsoft Visual C++ 2017 использовался до 1 сентября 2020 года.
  • MinGW GCC 7.1 использовался до 1 сентября 2020 года.
  • Clang 4.0.1 использовался до 1 сентября 2020 года.
  • Microsoft Visual C++ 2019 was used until January, 22 2024.
  • MinGW GCC 9.2 использовался до 22 января 2024 года.
  • Clang 10.0.0 использовался до 22 января 2024 года.