Existem alguns encurtamentos (shortcode) que se pode especificar para facilitar a escrita dos algoritmos. Na programação competitiva e necessário escrever os códigos o mais rápido possível e esses encurtamentos economizam algum tempo. A utilização desse tipo de otimização é válida quando a equipe já está com um bom desempenho na resolução de problemas, então inicialmente é importante se focar em resolver problemas e depois em conseguir fazer a codificação deles o mais rápido possível. Eles envolvem a especificação de typedefs e macros para as operações mais comuns.
Typedef
Um dos usos mais comuns de encurtamento é com a utilização do comando typedef. Com esse comando é possível encurtar o nome de um tipo de dado. Por exemplo, para encurtar a definição dos dados do tipo long long, é possível utilizar a instrução: typedef long long LL;
Com esse typedef, a declaração long long x; pode ser encurtada para LL x;
O ganho na quantidade de caracteres utilizados para escrever o código pode ser significativo para equipes bastante competitivas e que essa velocidade maior é importante. Cada equipe elabora seus próprios shortcodes e conforme sua necessidade, mas é importante que todos estejam acostumados com eles e as particularidades utilizadas pela equipe para definir os shortcodes.
Macros
As macros são trechos que serão substituídos antes da compilação do código e são especificadas utilizando a instrução #define.
Algumas macros podem ser bastante simples, como por exemplo o encurtamento para função push_back() da biblioteca vector. Utilizando #define PB push_back, é possível chamar essa função no código escrevendo somente PB(). O código abaixo ilustra como utilizar essa macro.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> myvector{ 1, 2, 3};
myvector.push_back(9);
for (int i=0; i<=3; i++) {
printf("%i ", myvector[i]);
}
}
Na linha 4 foi definida a macro e na linha 8 ela já foi utilizada para adicionar um valor ao vetor.
#include <iostream>
#include <vector>
using namespace std;
#define PB push_back
int main(){
vector<int> myvector{ 1, 2, 3};
myvector.PB(9);
for (int i=0; i<=3; i++) {
printf("%i ", myvector[i]);
}
}
A macro também pode ser utilizada para encurtar estruturas de dados, como é o caso do uso associado com o comando for. Com esse encurtamento será sempre mais fácil/rápido escrever as instruções for e como seu uso é bastante comum na codificação, sua economia de tempo é signitificativa.
int main(void) {
int t;
for (int i=2; i<=30; i++) {
printf("%i ", i);
}
return 0;
}
#define REP(i, a, b) for (int i=a; i<=b; i++)
int main(void) {
int t;
REP(i,2,30) {
printf("%i ", i);
}
return 0;
}
Veja que pode parecer um gasto de tempo escrever os shortcodes que trazem ganhos tão pequenos, mas em uma equipe um integrante começa escrevendo os shortcodes enquanto que os demais se debruçam lendo os problemas e identificando por qual começar.
Abaixo segue um template de shortcodes bastante comum e útil. Ele foi retirado de https://www.geeksforgeeks.org/c-methods-of-code-shortening-in-competitive-programming/
#include <bits/stdc++.h> // Include every standard library
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<string, string> pss;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<LL> vl;
typedef vector<vl> vvl;
double EPS = 1e-9;
int INF = 1000000005;
long long INFF = 1000000000000000005LL;
double PI = acos(-1);
int dirx[8] = { -1, 0, 0, 1, -1, -1, 1, 1 };
int diry[8] = { 0, 1, -1, 0, -1, 1, -1, 1 };
#ifdef TESTING
#define DEBUG fprintf(stderr, "====TESTING====\n")
#define VALUE(x) cerr << "The value of " << #x << " is " << x << endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define DEBUG
#define VALUE(x)
#define debug(...)
#endif
#define FOR(a, b, c) for (int(a) = (b); (a) < (c); ++(a))
#define FORN(a, b, c) for (int(a) = (b); (a) <= (c); ++(a))
#define FORD(a, b, c) for (int(a) = (b); (a) >= (c); --(a))
#define FORSQ(a, b, c) for (int(a) = (b); (a) * (a) <= (c); ++(a))
#define FORC(a, b, c) for (char(a) = (b); (a) <= (c); ++(a))
#define FOREACH(a, b) for (auto&(a) : (b))
#define REP(i, n) FOR(i, 0, n)
#define REPN(i, n) FORN(i, 1, n)
#define MAX(a, b) a = max(a, b)
#define MIN(a, b) a = min(a, b)
#define SQR(x) ((LL)(x) * (x))
#define RESET(a, b) memset(a, b, sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ALL(v) v.begin(), v.end()
#define ALLA(arr, sz) arr, arr + sz
#define SIZE(v) (int)v.size()
#define SORT(v) sort(ALL(v))
#define REVERSE(v) reverse(ALL(v))
#define SORTA(arr, sz) sort(ALLA(arr, sz))
#define REVERSEA(arr, sz) reverse(ALLA(arr, sz))
#define PERMUTE next_permutation
#define TC(t) while (t--)
inline string IntToString(LL a)
{
char x[100];
sprintf(x, "%lld", a);
string s = x;
return s;
}
inline LL StringToInt(string a)
{
char x[100];
LL res;
strcpy(x, a.c_str());
sscanf(x, "%lld", &res);
return res;
}
inline string GetString(void)
{
char x[1000005];
scanf("%s", x);
string s = x;
return s;
}
inline string uppercase(string s)
{
int n = SIZE(s);
REP(i, n)
if (s[i] >= 'a' && s[i] <= 'z')
s[i] = s[i] - 'a' + 'A';
return s;
}
inline string lowercase(string s)
{
int n = SIZE(s);
REP(i, n)
if (s[i] >= 'A' && s[i] <= 'Z')
s[i] = s[i] - 'A' + 'a';
return s;
}
inline void OPEN(string s)
{
#ifndef TESTING
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
#endif
}
// end of Sektor_jr template v2.0.3 (BETA)
int main()
{
freopen("A.in", "r", stdin);
freopen("output.txt", "w", stdout);
int a, b;
fin >> a >> b;
fout << a + b << endl;
return 0;
}