[2] Código base de C++ para programación competitiva

0 163
Avatar for kalawasa
2 years ago

Si estas empezando con C++ para programación competitiva, te puede interesar tener un archivo compacto base (una plantilla) para empezar a resolver nuestros problemas. Este archivo tendrá lo necesario para ser usado en cualquier escenario en el que tengamos que programar soluciones rápidas como es el caso de la programación competitiva.

El código base

Es la estructura de código principal que permite ejecutar nuestra solución.

#include <bits/stdc++.h>
using namespace std;

int main() {
	
	ios_base::sync_with_stdio(0); cin.tie(0);

	/* aquí vendrá el código de su solución */

	return 0;
}

Cada linea de código tiene un propósito, y son:

  • #include <bits/stdc++.h> , incluirá toda la librería estándar de GNU C++ (STL), en otras palabras copiará y pegara todo el código contenido en este archivo, con esto nos ahorramos tiempo de escribir en la cabecera cada librería que usemos, esta opción no es una buena idea para la programación convencional, porque incluirá cosas innecesarias y aumentaría el tiempo de compilación.

  • using namespace std; , es el espacio de nombre que agrupa y define todo un bloque estándar de funciones, variables entre otros. Aquí se encuentra definido las funciones de entrada y salida estándar como son cout y cin .

  • int main() {} , es la función principal donde se iniciará la ejecución de nuestro programa, cada archivo .cpp que creemos debe tener esta función.

  • ios_base::sync_with_stdio(0); cin.tie(0); , es la declaración de entrada y salida rápida, permite recibir entradas (cin) sin esperar a alguna salida (cout) que pudiera aparecer en el proceso, osea deshabilita la sincronización entre cin y cout, en el caso de programación competitiva es muy útil en la mayoría de los problemas porque se reciben grandes cantidades de datos y se espera una respuesta por cada uno de ellos, pero no es necesario mostrar la respuesta uno por uno, esta linea de código permite almacenar las respuestas en un buffer y luego mostrar todo de golpe. Una alternativa para entradas y salidas rápidas es usar scanf y printf que cumplen la misma función, si se usa estas funciones esta linea de código es innecesaria. También hay que tener en cuenta que si se usa esta linea de código no podemos usar cin y cout junto con scanf y printf . En el caso de problemas interactivos no agregar esta linea en su código.

  • return 0; , es la respuesta o retorno de la función main(), la documentación también indica que si el código dentro de la función main() termina y no encuentra el return, este ejecutará implícitamente return 0; .

¿Qué mas podemos agregar a nuestra plantilla?

Hay dos opciones que son muy usadas por programadores competitivos, son los MACROS y TYPEDEFS, estas cumplen la función de abreviar el código de manera que facilitan la velocidad de tipeo y codificación, antes de usarlos yo recomiendo familiarizarse con el entorno de C++.

MACRO

Son porciones de código que son definidas por la directiva #define . Cuando el compilador encuentre una macro, reemplaza el nombre con la definición de la macro, por ejemplo:

#include <bits/stdc++.h>
using namespace std;

#define FIN ios_base::sync_with_stdio(0); cin.tie(0);
#define sz(x) int((x).size())
#define FOR(i,a,b) for (int i = (a); i < (b); i++)

int main() {FIN
	
	vector<long long> v = {1, 2, 3, 4, 5};
	
	FOR(i, 0, sz(v)) {
		cout << v[i] << "\n";
	}
	
	return 0;
}

En este ejemplo primero definimos la entrada y salida rápida con la macro FIN, para llamarlo luego al inicio en la función main , seguidamente declaramos un vector el cual queremos iterar usando la macro FOR(i,a,b) y la macro sz(x) . Ahora cuando se realice la compilación las macros serán reemplazadas y quedara algo similar a:

#include <bits/stdc++.h>
using namespace std;

#define FIN ios_base::sync_with_stdio(0); cin.tie(0);
#define sz(x) int((x).size())
#define FOR(i,a,b) for (int i = (a); i < (b); i++)

int main() {ios_base::sync_with_stdio(0); cin.tie(0);
	
	vector<long long> v = {1, 2, 3, 4, 5};
	
	for (int i = 0; i < int(v.size()); i++) {
		cout << v[i] << "\n";
	}
	
	return 0;
}

Cabe resaltar que se puede usar macros ya definidas en otras macros.

TYPEDEF

Permite dar un nombre mas corto a un tipo de dato existente, por ejemplo:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<ll> vll;

int main() {ios_base::sync_with_stdio(0); cin.tie(0);
	
	vll v = {1, 2, 3, 4, 5};
	
	for (int i = 0; i < int(v.size()); i++) {
		cout << v[i] << "\n";
	}
	
	return 0;
}

Aquí declaramos dos nuevos typedef para el tipo de dato long long y la estructura de datos vector<> de tipo long long , también es posible usar typedef en otros typedef. Ahora juntemos nuestras macros y typedefs, nos daremos cuenta que el contenido de la función main es más fácil y rápido de escribir, nuestra nueva plantilla ahora sera todo lo que está fuera de la función main .

#include <bits/stdc++.h>
using namespace std;

#define FIN ios_base::sync_with_stdio(0); cin.tie(0);
#define sz(x) int((x).size())
#define FOR(i,a,b) for (int i = (a); i < (b); i++)

typedef long long ll;
typedef vector<ll> vll;

int main() {FIN
	
	vll v = {1, 2, 3, 4, 5};
	
	FOR(i, 0, sz(v)) {
		cout << v[i] << "\n";
	}
	
	return 0;
}

Llegando a este punto usted puede decidir que tanto y en que medida esta dispuesto a usar las abreviaciones de código.

Referencias y más

1
$ 0.00
Sponsors of kalawasa
empty
empty
empty
Avatar for kalawasa
2 years ago

Comments