Implementación en C++ del problema P1188 PASTE de la Olimpiada Informática

El problema P1188 PASTE consiste en simular operaciones de cortar y pegar sobre un archivo de texto que contiene inicialmente números naturales del 1 al N, uno por línea. Se deben realizar K operaciones y luego mostrar las primeras 10 líneas del resultado.

Descirpción del problema

Se tiene un archivo con N líneas (N entre 10 y 100.000). Cada línea contiene un número natural: la línea i contiene el número i. Se aplican K operaciones (1 ≤ K ≤ 1000). Cada operación viene dada por tres enteros A, B, C:

  • Se seleccionan las líneas desde A hasta B (inclusive)
  • Se cortan (eliminan del archivo)
  • Se pegan inmediatamente después de la línea C (si C = 0, se pegan al inicio del archivo)

Se debe imprimir el contenido de las primeras 10 líneas después de todas las operaciones.

Entrada y salida

Entrada: Primera línea con N y K. Luego K líneas, cada una con A, B, C.

Salida: 10 líneas con los números correspondientes a las primeras 10 líneas finales.

Ejemplo

Entrada:


13 3
6 12 1
2 9 0
10 13 8

Salida:


6
7
8
9
10
11
12
2
3
4

Solución en C++

La implementación utiliza un arreglo para representar el documento y un arreglo tempoarl para almacenar el fragmento cortado. Se manipulan los índices manualmente para desplazar los elementos. A continuación se muestra el código reescrito con cambios de estructura y nombres de variables:

#include <iostream>
using namespace std;

const int MAX = 100005;
int doc[MAX], buffer[MAX];
int n, k;

int main() {
    // Inicializar documento con valores 1..N
    for (int i = 1; i < MAX; i++) doc[i] = i;
    cin >> n >> k;
    
    for (int op = 0; op < k; op++) {
        int a, b, pos;
        cin >> a >> b >> pos;
        int len = b - a + 1;
        int dest_start = pos + 1;
        int dest_end = dest_start + len - 1;
        int idx = 0;
        
        // Copiar fragmento a buffer
        for (int i = a; i <= b; i++) buffer[++idx] = doc[i];
        
        // Desplazar elementos según corresponda
        if (pos < a) {
            // El destino está antes del fragmento: mover hacia la derecha
            for (int i = a - 1; i >= dest_start; i--) 
                doc[i + len] = doc[i];
        } else {
            // El destino está después del fragmento: mover hacia la izquierda
            for (int i = b + 1; i <= dest_end; i++) 
                doc[i - len] = doc[i];
        }
        
        // Insertar el fragmento en la posición destino
        idx = len;
        for (int i = dest_end; i >= dest_start; i--) 
            doc[i] = buffer[idx--];
    }
    
    // Mostrar las primeras 10 líneas
    for (int i = 1; i <= 10; i++) 
        cout << doc[i] << endl;
    
    return 0;
}

Explicación del código

Se usa un arreglo doc donde la posición i almacena el número de la línea i. En cada operación:

  1. Se copia el segmento [a, b] al buffer.
  2. Se desplazan los elementos entre el fragmento y la posición destino para hacer espacio.
  3. Se copia el buffer de vuelta al documento en la posición destino.

El desplazamiento se hace con cuidado dependiendo de si la posición de inserción está antes o después del fragmento original, evitando sobrescribir datos no copiados.

Etiquetas: C++ Olimpiada Informática corte y pegado Simulación arreglos

Publicado el 8-25 10:44