Skip to Content

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)
  1. 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 NN elementos ordenándolo con comparador.
  2. 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).
  3. 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 TT 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 ans
static 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 [l,r][l, r] en tiempo O(1)\mathcal{O}(1).

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) pass

Checklist 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: ¿N105    O(NlogN)N \le 10^5 \implies \mathcal{O}(N \log N)? ¿N20    O(2N)N \le 20 \implies \mathcal{O}(2^N)? ¿N500    O(N3)N \le 500 \implies \mathcal{O}(N^3)? (Recordar: aproximadamente 10810^8 operaciones por segundo).
  • Desbordamiento de Enteros (Integer Overflow): ¿Algún cálculo intermedio (como sumas acumuladas, productos o fórmulas N(N1)2\frac{N(N-1)}{2}) puede superar 21092 \cdot 10^9? Si la respuesta es sí, usá long long en C++ o long en Java.
  • Casos Extremos (Edge Cases):
    • N=1N = 1 o N=0N = 0.
    • 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 (TT), ¿reiniciaste todos los vectores, matrices de adyacencia y arreglos visited al inicio de cada caso?
  • Indexación: ¿El enunciado usa índices 11-based o 00-based? ¿Las consultas son inclusivas o semi-abiertas?
  • Formato de Salida: ¿Requiere saltos de línea \n o espacios? ¿Se pide imprimir YES/NO con 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)

  1. Weird Algorithm: Simulación elemental de Collatz.
  2. Missing Number: Sumas y propiedades aritméticas o XOR.
  3. Repetitions: Recorrido lineal y actualización de máximos.
  4. 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)

  1. Two Sum (HashMap / Two Pointers en versión ordenada).
  2. Valid Palindrome (Two pointers con limpieza de caracteres).
  3. Contains Duplicate (HashSet / Sorting).
  4. Maximum Subarray (Algoritmo de Kadane).

¡Hacé del calentamiento un hábito antes de cada sesión para competir con máxima claridad mental!