E/S rápida para programación competitiva

En la programación competitiva, es importante leer la entrada lo más rápido posible para ahorrar un tiempo valioso.

Debe haber visto varias declaraciones de problemas que dicen: » Advertencia: datos de E / S grandes, tenga cuidado con ciertos idiomas (aunque la mayoría debería estar bien si el algoritmo está bien diseñado)» . La clave para estos problemas es utilizar técnicas de E/S más rápidas. 

A menudo se recomienda usar scanf/printf en lugar de cin/cout para una entrada y salida rápidas. Sin embargo, aún puede usar cin/cout y lograr la misma velocidad que scanf/printf al incluir las siguientes dos líneas en su función main():

    ios_base::sync_with_stdio(false);

Activa o desactiva la sincronización de todos los flujos estándar de C++ con sus flujos de C estándar correspondientes si se llama antes de que el programa realice su primera operación de entrada o salida. Agregar ios_base::sync_with_stdio (falso); (que es cierto de forma predeterminada) antes de cualquier operación de E/S evita esta sincronización. Es un miembro estático de la función de std::ios_base. 

    cin.tie(NULL);

tie() es un método que simplemente garantiza el vaciado de std::cout antes de que std::cin acepte una entrada. Esto es útil para los programas de consola interactiva que requieren que la consola se actualice constantemente, pero también ralentiza el programa para grandes E/S. La parte NULL simplemente devuelve un puntero NULL.

Además, puede incluir la biblioteca de plantillas estándar (STL) con una sola inclusión:  

    #include <bits/stdc++.h>

Entonces, su plantilla para la programación competitiva podría verse así:  

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

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    return 0;
}

Se recomienda utilizar cout << “\n”; en lugar de cout << endl;. endl es más lento porque fuerza un flujo de descarga, que generalmente es innecesario (consulte esto para obtener más detalles). (Necesitaría vaciar si estuviera escribiendo, digamos, una barra de progreso interactiva, pero no cuando escriba un millón de líneas de datos). Escriba ‘\n en lugar de endl.

Podemos probar nuestros métodos de entrada y salida en el problema INTEST – Enormous Input Teston SPOJ. Antes de seguir leyendo, le sugiero que primero resuelva el problema.
Solución en C++ 4.9.2

E/S normal: el siguiente código usa cin y cout. La solución se acepta con un tiempo de ejecución de 2,17 segundos. 

C++

// A normal IO example code
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, k, t;
    int cnt = 0;
    cin >> n >> k;
    for (int i=0; i<n; i++)
    {
        cin >> t;
        if (t % k == 0)
            cnt++;
    }
    cout << cnt << "\n";
    return 0;
}

E/S rápida Sin embargo, podemos hacerlo mejor y reducir mucho el tiempo de ejecución agregando dos líneas. El siguiente programa se acepta con un tiempo de ejecución de 0,41 segundos.

C++

// A fast IO program
#include <bits/stdc++.h>
using namespace std;
  
int main()
{
    // added the two lines below
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);   
      
    int n, k, t;
    int cnt = 0;
    cin >> n >> k;
    for (int i=0; i<n; i++)
    {
        cin >> t;
        if (t % k == 0)
            cnt++;
    }
    cout << cnt << "\n";
    return 0;
}

Ahora, hablando de concursos competitivos como ACM ICPC, Google CodeJam, TopCoder Open, aquí hay un código exclusivo para leer números enteros de la manera más rápida.

C++

void fastscan(int &number)
{
    //variable to indicate sign of input number
    bool negative = false;
    register int c;
  
    number = 0;
  
    // extract current character from buffer
    c = getchar();
    if (c=='-')
    {
        // number is negative
        negative = true;
  
        // extract the next character from the buffer
        c = getchar();
    }
  
    // Keep on extracting characters if they are integers
    // i.e ASCII Value lies from '0'(48) to '9' (57)
    for (; (c>47 && c<58); c=getchar())
        number = number *10 + c - 48;
  
    // if scanned input has a negative sign, negate the
    // value of the input number
    if (negative)
        number *= -1;
}
  
// Function Call
int main()
{
    int number;
    fastscan(number);
    cout << number << "\n";
    return 0;
}

getchar_unlocked() para una entrada más rápida en C para una programación competitiva 
 

Este artículo es una contribución de Vinay Garg. Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *