Zona de calentamiento (Warm up)
El calentamiento (warm-up) en programación algorítmica cumple el mismo rol que en cualquier disciplina de alto rendimiento: despejar la inercia mental, reconectar la memoria muscular de los dedos con la sintaxis del lenguaje y calibrar la precisión en los casos borde.
Comenzar una ronda de competencia o una entrevista técnica en frío aumenta drásticamente la probabilidad de cometer errores elementales (como off-by-one, desbordes de enteros o bloqueos mentales en problemas sencillos).
La Rutina de 15 Minutos
Antes de un contest o una sesión de práctica intensa, dedicá exactamente 15 minutos repartidos en tres bloques:
[ 00:00 - 05:00 ] ──> [ 05:00 - 10:00 ] ──> [ 10:00 - 15:00 ]
Mecánica & I/O Drill de Patrón Problema Express
(Plantilla + Lectura) (Binary Search / TP) (Div 2 A / Easy)- Minutos 0 a 5: Mecánica y lectura de datos. Abrí tu editor, escribí tu plantilla base de memoria, configurá la entrada rápida y leé un arreglo de elementos ordenándolo con comparador.
- Minutos 5 a 10: Drill de un patrón estándar. Escribí una función elemental de memoria: una búsqueda binaria sin usar funciones de biblioteca, o una suma de prefijos 2D, o un recorrido BFS en matriz con matriz de direcciones (
dx/dy). - Minutos 10 a 15: Problema express. Resolvé un problema elemental (por ejemplo, un Codeforces Div 2 A o un LeetCode Easy de strings/arreglos) apuntando a obtener veredicto aceptado (Accepted) en el primer envío.
Batería de Drills de Implementación Rápida
Los siguientes ejercicios están pensados para escribirse en menos de 2 minutos cada uno. Si dudas en algún punto, practicá escribirlo varias veces hasta que el patrón sea automático.
Drill 1: Entrada/Salida Rápida y Múltiples Casos
Estructura para leer casos de prueba con enteros y strings sin problemas de búfer.
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
if (!(cin >> n)) return;
vector<long long> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
// Lógica del caso
cout << a[0] << "\n";
}
int main() {
// Desacoplar streams de C/C++ y vaciar buffer automáticamente
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}import sys
def solve():
input = sys.stdin.readline
line = input().strip()
if not line:
return
n = int(line)
a = list(map(int, input().split()))
# Lógica del caso
sys.stdout.write(f"{a[0]}\n")
def main():
input = sys.stdin.readline
line = input().strip()
if not line:
return
t = int(line)
for _ in range(t):
solve()
if __name__ == '__main__':
main()import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringTokenizer;
import java.io.IOException;
public class Main {
static class FastReader {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
String line = br.readLine();
if (line == null) return null;
st = new StringTokenizer(line);
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() { return Integer.parseInt(next()); }
long nextLong() { return Long.parseLong(next()); }
}
public static void main(String[] args) {
FastReader in = new FastReader();
String tStr = in.next();
if (tStr == null) return;
int t = Integer.parseInt(tStr);
while (t-- > 0) {
int n = in.nextInt();
long[] a = new long[n];
for (int i = 0; i < n; i++) a[i] = in.nextLong();
System.out.println(a[0]);
}
}
}Drill 2: Búsqueda Binaria Manual Infallible
Implementar búsqueda binaria sin riesgo de bucles infinitos (el clásico (low + high) / 2 que no avanza cuando low + 1 == high).
// Encuentra el primer índice donde a[idx] >= x (lower_bound)
int lower_bound_manual(const vector<int>& a, int x) {
int low = 0, high = (int)a.size() - 1;
int ans = a.size(); // Valor por defecto si todos son menores que x
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] >= x) {
ans = mid;
high = mid - 1; // Buscar una posición aún más a la izquierda
} else {
low = mid + 1;
}
}
return ans;
}def lower_bound_manual(a: list[int], x: int) -> int:
low, high = 0, len(a) - 1
ans = len(a)
while low <= high:
mid = low + (high - low) // 2
if a[mid] >= x:
ans = mid
high = mid - 1 # Buscar más a la izquierda
else:
low = mid + 1
return ansstatic int lowerBoundManual(int[] a, int x) {
int low = 0, high = a.length - 1;
int ans = a.length;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] >= x) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}Drill 3: Sumas de Prefijos 1D con Indexación 1-based
El patrón estándar para responder consultas de suma en rango en tiempo .
vector<long long> build_pref(const vector<int>& a) {
int n = a.size();
vector<long long> pref(n + 1, 0);
for (int i = 0; i < n; i++) {
pref[i + 1] = pref[i] + a[i];
}
return pref;
}
// Suma de a[l..r] (índices 0-based inclusivos)
long long query_sum(const vector<long long>& pref, int l, int r) {
return pref[r + 1] - pref[l];
}def build_pref(a: list[int]) -> list[int]:
n = len(a)
pref = [0] * (n + 1)
for i in range(n):
pref[i + 1] = pref[i] + a[i]
return pref
def query_sum(pref: list[int], l: int, r: int) -> int:
return pref[r + 1] - pref[l]Drill 4: Recorrido en Matriz con Vectores de Dirección (dx/dy)
El mecanismo estándar para explorar celdas vecinas (4 u 8 direcciones) en grafos de grillas sin código repetitivo.
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1};
bool is_valid(int r, int c, int rows, int cols) {
return r >= 0 && r < rows && c >= 0 && c < cols;
}
void traverse_neighbors(int r, int c, int rows, int cols) {
for (int dir = 0; dir < 4; dir++) {
int nr = r + dx[dir];
int nc = c + dy[dir];
if (is_valid(nr, nc, rows, cols)) {
// Procesar celda vecina (nr, nc)
}
}
}DIRS = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def traverse_neighbors(r: int, c: int, rows: int, cols: int):
for dr, dc in DIRS:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols:
# Procesar celda vecina (nr, nc)
passChecklist Pre-Contest / Pre-Entrevista
Antes de enviar una solución o confirmar tu código frente al entrevistador, verificá estos 6 puntos críticos:
- Límites de Tiempo vs Operaciones: ¿? ¿? ¿? (Recordar: aproximadamente operaciones por segundo).
- Desbordamiento de Enteros (Integer Overflow): ¿Algún cálculo intermedio (como sumas acumuladas, productos o fórmulas ) puede superar ? Si la respuesta es sí, usá
long longen C++ olongen Java. - Casos Extremos (Edge Cases):
- o .
- Todos los elementos iguales (ej.
[5, 5, 5, 5]). - Arreglo ya ordenado en orden ascendente o estrictamente descendente.
- Valores negativos o todos ceros.
- Cadenas vacías o con un único caracter.
- Limpieza de Estructuras Globales: Si el problema tiene múltiples casos de prueba (), ¿reiniciaste todos los vectores, matrices de adyacencia y arreglos
visitedal inicio de cada caso? - Indexación: ¿El enunciado usa índices -based o -based? ¿Las consultas son inclusivas o semi-abiertas?
- Formato de Salida: ¿Requiere saltos de línea
\no espacios? ¿Se pide imprimirYES/NOcon mayúsculas exactas?
Colección Curada de Problemas para Calentar
Para activar la mente en los primeros 10-15 minutos de práctica:
En CSES (Introductory Problems)
- Weird Algorithm: Simulación elemental de Collatz.
- Missing Number: Sumas y propiedades aritméticas o XOR.
- Repetitions: Recorrido lineal y actualización de máximos.
- Increasing Array: Estrategia codiciosa (greedy) inmediata.
En AtCoder (ABC A & B)
- Cualquier problema A o B de las rondas AtCoder Beginner Contest recientes (ideal para entrenar precisión y velocidad de lectura).
En LeetCode (Warm-up Essentials)
- Two Sum (HashMap / Two Pointers en versión ordenada).
- Valid Palindrome (Two pointers con limpieza de caracteres).
- Contains Duplicate (HashSet / Sorting).
- Maximum Subarray (Algoritmo de Kadane).
¡Hacé del calentamiento un hábito antes de cada sesión para competir con máxima claridad mental!