Saltar a contenido

E/S rápida#

Metadatos

Tipo: Técnica · Nivel: Principiante · Dificultad: 1.0

Requisitos: Input/Output 🏗️

Relacionado: Bucles

En muchos problemas la entrada es enorme (cientos de miles de números). Leerla o escribirla de forma lenta hace que el programa supere el límite de tiempo (Time Limit Exceeded) aunque el algoritmo sea correcto. La solución no cambia tu algoritmo: solo cambia cómo lees y escribes. La idea es una: no proceses la E/S carácter a carácter; trabájala en bloque.

¿Por qué es lento por defecto?#

  • C++ — Por compatibilidad, cin/cout están sincronizados con el scanf/printf de C y, además, cin está atado a cout (antes de cada lectura se vacía la salida). Eso cuesta tiempo en cada operación. Se desactiva con dos líneas al principio de main():

    ios::sync_with_stdio(false);   // desliga cin/cout del stdio de C
    cin.tie(nullptr);              // no vaciar cout antes de cada cin
    

    Además, usa '\n' en lugar de endl: endl imprime un salto de línea y vacía el búfer cada vez; dentro de un bucle eso es carísimo.

    Al desactivar la sincronización

    No mezcles cin/cout con scanf/printf en el mismo programa: al perder la sincronización, el orden de la salida puede desordenarse.

  • Python — La función input() es cómoda pero lenta si la llamas miles de veces. Lo básico es reemplazarla por el lector con búfer sys.stdin.readline; y si hay muchísimos números, leer todo de una vez con sys.stdin.read().split(). Para imprimir mucho, junta todo y escríbelo de golpe ("\n".join(...)) en lugar de un print por línea.

Plantilla mínima#

Esto es lo único que necesitas recordar (también está en el chuletario):

// C++ fast I/O — put these two lines first, inside main():
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Then read/print as usual:  cin >> x;   cout << x << '\n';
// (use '\n', never endl inside loops — endl flushes the buffer every time).
# Python fast I/O — swap input() for the buffered reader (drop-in, at the top):
import sys
input = sys.stdin.readline
# input().split() reads one line; for many tokens at once: sys.stdin.read().split().
# Print a lot in one go:  print("\n".join(map(str, answers)))

Ejemplo completo#

Un programa que lee n números y muestra su suma, ya con la E/S rápida aplicada. Fíjate en que el algoritmo (sumar) es trivial: lo único "especial" es la preparación de la E/S.

/**
 * Fast I/O — read many integers quickly and print their sum.
 *
 * `ios::sync_with_stdio(false)` + `cin.tie(nullptr)` unhook the C++ streams from
 * C stdio; on large inputs this is dramatically faster and avoids Time Limit
 * Exceeded.
 *
 * Input:  an integer n, then n integers.
 * Output: the sum of the n integers.
 */
#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        sum += x;
    }
    cout << sum << "\n";
    return 0;
}
"""Fast I/O — read many integers quickly and print their sum.

Reading the whole input at once with `sys.stdin.buffer.read()` is much faster
than calling `input()` in a loop, which avoids Time Limit Exceeded on big cases.

Input:  an integer n, then n integers.
Output: the sum of the n integers.
"""
import sys


def main() -> None:
    data: list[bytes] = sys.stdin.buffer.read().split()
    n: int = int(data[0])
    total: int = sum(int(x) for x in data[1:1 + n])
    print(total)


main()
Entrada Salida
5
1 2 3 4 5
15
3
10 20 30
60

¿Cuándo hace falta?

Si el enunciado maneja entradas grandes (≈10⁵ valores o más) o tienes un TLE que no explicas por complejidad, aplica esta plantilla. En entradas pequeñas no cambia nada, así que puedes ponerla siempre por costumbre.