Полезные фишки, которые серьёзно упрощают работу под линуксом, и в частности под IOI-окружением, отмечены красными восклицательными знаками (!).
Шпаргалка по командам (bash):
(!) Сильно упрощает работу с терминалом включение цветного режима, который подсвечивает приглашение bash, а также вывод разных команд (например, папки в выводе ls будут окрашены в синий цвет). Для этого надо открыть файл ~/.bashrc, раскомментировать в нём строку #force_color_prompt=yes (удалить решётку из начала) и перезапустить терминал.
(!!) В баше есть автодополнение путей, которое очень ускоряет набор команд. Во время набора пути (или просто имени файла) можно нажать один или два раза кнопку tab. Например, пусть в текущей директории есть три файла: main_stup.cpp, main_opt.cpp и gen.cpp. Тогда можно вывести содержимое файла main_opt.cpp следующей последовательностью нажатий:
~/dir$ cat m<TAB> # в этот момент баш понимает, что дальше будет точно main_, и дополняет ~/dir$ cat main_<TAB><TAB> # баш не знает, хотим ли мы stup или opt, поэтому он выводит оба варианта main_opt.cpp main_stup.cpp ~/dir$ cat main_o<TAB> ~/dir$ cat main_opt.cpp
(!) В путях можно пользоваться плейсхолдерами (звёздочками и вопросиками). Например, cp main* dir/ в предыдущем примере скопирует все файлы, начинающиеся на main, в папку dir/
g++ main.cpp -o main [-O2] [-g] [-fsanitize=address] — скомпилировать исходник main.cpp на C++ в исполняемый файл main
Ключ -O2 включает режим оптимизации, с таким ключом ваши решения компилируется в тестирующей системе.
Ключ -g добавляет в исполняемый файл отладочную информацию, необходимо для последующей отладки с помощью gdb
(!!) Ключ -fsanitize=address добавляет вспомогательный код, который отлавливает ошибки неправильного обращения к памяти (в частности, выходы за границы массива, использование непроинициализированных переменных и прочее). Этот ключ очень замедляет исполнение, но позволяет убедиться, что у вас нет проезда по памяти
fpc main.pas -omain [-O2] [-g] — скомпилировать исходник main.cpp на C++ в исполняемый файл main
Смысл ключей тот же самый, что и в g++.
Запустить решение: ./main [<IN] [>OUT], с помощью угловых скобок можно перенаправить из файла IN или в файл OUT
Запустить скрипт на Питоне: python main.py [<IN] [>OUT]
(!) Убрать ограничение на размер стека (влияет на всю сессию bash): ulimit -s unlimited
Измерить время работы решения: time ./main <in.txt >out.txt
while true do # генерируем тест python gen.py >test.in # или (если вы пишете на плюсах) ./gen >test.in # конструкция "|| break" выкидывает из цикла если код выхода main ненулевой ./main <test.in >test.out || break # пусть naive это тупое решение ./naive <test.in >test.out || break # если ответ не единственный, то придётся написать чекер и сделать так, чтобы # он выходил с кодом возврата 0, если ОК, и с кодом возврата не 0, если не ОК # иначе подходит обыкновенный diff diff output.txt answer.txt || break done
for t in 01 02 03 50 99 do # это в предположении, что входные данные называются 01, 02 и так далее, ответы попадут в 01.r, ... ./main <$t >$t.r done
(!) Вместо явного перечисления тестов можно пользоваться шаблонами. Например: input_*.txt это все файлы, где вместо звёздочки стоит 0 или больше символов, ?? это все файлы, состоящие из ровно двух символов. Это может быть полезно, чтобы, например, удалить все файлы, обладающие каким-то расширением: rm *.r.
# Компилируем с ключом -g. ~/dir$ g++ main.cpp -o main -g ~/dir$ gdb main # Вывалится большое приглашение. Можно вводить команды gdb. # r означает запустить программу, можно указать произвольные аргументы командной # строки, например, перенаправить ввод откуда-нибудь. (gdb) r <test.in # Предположим, программа где-то упала. # bt от слова backtrace - показать стек исполнения. (gdb) bt # Если мы слишком глубоко по стеку (например в глубинах STL-ной реализации вектора), # можно перемещаться по стеку командами up и down. (gdb) up # p от слова print - напечатать значение переменной (gdb) p arr[0] (gdb) p x # Чтобы поставить breakpoint, надо написать b [номер строки] или b [название функции]. (gdb) b main # Чтобы удалить breakpoint, надо написать clear [номер строки] или clear [название функции]. # Запускаем программу заново. (gdb) r <test.in # Step out (без захода в функцию) делается с помощью команды n, step in с помощью команды s. (gdb) n (gdb) s # Выйти из GDB - нажать ctrl-D. (gdb) <ctrl>-D