Rumb Necesita una Mano
Este problema consiste en, dada una permutación p de longitud n, determinar si es posible ordenarla de forma creciente realizando exactamente una operación: elegir un conjunto de índices (no necesariamente consecutivos) y revertir los elementos que se encuentran en esas posiciones.
Por ejemplo, con p = [1, 6, 3, 4, 5, 2] se pueden elegir los índices 2, 4 y 6; los elementos en rojo se invierten y la permutación queda ordenada.
Solución
#include "iostream"
#include <vector>
using namespace std;
int main (int argc, char *argv[]) {
int n;
cin>> n;
for (size_t i = 0; i < n ; i++) {
int k;
cin>>k;
vector<int> l(k);
for (size_t i = 0; i < k; i++) {
cin>>l[i];
}
std::vector<int> v;
for (size_t i = 0; i < k; i++) {
if (l[i]!=i+1){
v.push_back(i+1);
}
}
bool possible = true;
int len = v.size();
int err = 1;
for (size_t i = 0; i < k; i++) {
if (l[i]!=i+1){
if (v[len-err]!=l[i]){
cout<<"NO\n";
possible = false;
break;
}
err+=1;
}
}
if (possible)
cout<<"YES\n";
}
return 0;
}
Para que una sola reversión ordene la permutación, los índices elegidos deben ser exactamente las posiciones donde el valor no coincide con su índice (p[i] != i). Además, al revertir, la posición i_j recibe el valor que estaba en la posición reflejada i_{m-j+1}, por lo que el valor en cada posición desordenada debe ser igual a la posición desordenada simétrica.
La solución primero guarda en v todas las posiciones (1-indexadas) donde l[i] != i + 1. Después recorre el arreglo y, en cada posición desordenada, compara su valor con la posición correspondiente leída desde el final de v (con el contador err avanzando). Si todos coinciden, la permutación se puede ordenar con una sola operación y se imprime YES; en caso contrario se imprime NO.