Programação Competitiva
Vamos começar apresentando alguns dos recursos da linguagem de programação C++ que são úteis na programação competitiva. Todos os comandos serão dados considerando o Linux como Sistema Operaciona. Caso esteja usando Windows, use o CS50 IDE ou VSCode for CS50.
Características da linguagem
-
Recurso do compilador
g++que permite incluir toda a biblioteca padrão. Assim, não é necessário incluir separadamente bibliotecas comoiostream,vector, ealgorithm. Clique aqui para saber mais. -
Declara que as classes e funções da biblioteca padrão podem ser usadas diretamente no código. Sem essa linha teríamos que escrever, por exemplo,
std::coutao invés de apenascout.
O código pode ser compilado usando o seguinte comando:
O comando produz um arquivo binário, chamado programa, a partir do código-fonte main.cpp. Leia mais aqui.
Para evitar bugs comuns, sempre iremos compilar o código com algumas flags de compilação:
g++ -O2 -std=c++17 -Wshadow -fsanitize=address,undefined -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable main.cpp -o programa
Para facilitar a compilação e execução do código, crie um arquivo chamado cr e adicione o seguinte código:
g++ -O2 -std=c++17 -Wshadow -fsanitize=address,undefined -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable $1 -o programa && time ./programa < in
No terminal, execute o comando chmod +x cr para dar direitos de execução ao arquivo cr. Para usá-lo basta passar como argumento um arquivo .cpp, por exemplo, ./cr main.cpp. O código será compilado e, em caso de sucesso, será gerado um programa chamado programa que será executado considerando o arquivo in como dado de entrada. Ao usar o arquivo in, não precisamos digitar os dados de entrada.
Entrada e Saída
Na maioria dos contests, é necessário ler da entrada padrão (teclado) e escrever algo. Em C++, é usado o cin para leitura e cout para saída. Também podem ser usado as funções de C, como scanf e printf.
A entrada do programa geralmente consiste em números e strings separados por espaços e/ou novas linhas. Eles podem ser lidos a partir do cin da seguinte forma:
Considerando que há ao menos um espaço em branco ou uma nova linha entre cada elemento da entrada, esse código sempre funciona.
O cout pode ser usado da seguinte forma:
- Um espaço em branco irá separar cada informação. Ao fim, uma linha em branco (
\n) será gerada.
Às vezes, a entrada e a saída podem ser um gargalo em um programa. Por isso, é comum ser adicionado as seguintes linhas no início do código:
Atenção
Ao usar o comando ios_base::sync_with_stdio(0);, será desativado a sincronização entre as função de C++ e C, por isso não use as função de entrada e saída de C (scanf e printf) junto com esse comando.
Alternativamente ao \n podemos usar o comando endl. Entretanto, este comando irá liberar o buffer de saída e fará com que o código rode mais lento. Por isso, prefira usar o \n.
Dica
Use sempre o \n ao invés do endl. Use uma macro #define endl '\n' para não correr o risco de esquecer.
Para se aprofundar mais:
Trabalhando com números
- Inteiros: Para evitar integer overflow, use sempre
long long(64bits) ao invés deint. - Reais: Use
double(64bits) oulong double(80bits). Esqueça ofloat😅. Além disso, nunca compare doisdoublecom o operador==(é possível que os valores sejam iguais, mas não são devido a erros de precisão). Para verificar se doisdoubleuse o código a seguir:
Para saber mais: Data Types
Simplificando o código
Nomes de tipos
Usando o comando typedef é possível dar um nome mais curto a um tipo de dado. Por exemplo:
Macros
Uma macro significa que certas palavras no código serão substituídas antes da compilação. Em C++, as macros são definidas usando a palavra-chave #define. Veja alguns exemplos:
Assim, por exemplo, o código for(long long i = 0; i < n; ++i) pode ser simplificado por FOR(i, 0, n).
Dicas e truques de C++
A seguir, são listados alguns links com dicas e truques de C++ úteis para programação competitiva. Leia todos com atenção: