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:
- Se copia el segmento [a, b] al buffer.
- Se desplazan los elementos entre el fragmento y la posición destino para hacer espacio.
- 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.