CF1333D Desafíos en la escuela №41 (Pensamiento)

Para una clase de problemas de construcción. Siempre descubro la situación que no se puede construir, y luego pienso en la construcción.

En este problema, si este k puede construirse entre los tiempos de construcción mínimo y máximo, entonces puede construirse

La pregunta ahora es cómo encontrar el mínimo y el máximo. Para la inversión del título, también podríamos considerarlo como un intercambio, por lo que el caso más pequeño es en realidad un intercambio una vez, es decir, el número de pares en orden inverso

La situación más grande es cambiar todos los artículos intercambiables cada vez. En primer lugar, podemos pensar que cada pariente debe ser relativo cuando no hay intercambio, es decir, debe intercambiarse, independientemente del número de otros equipos, por lo que todo intercambio es lo mejor para cada intercambio.

Ahora considere cómo cambiar lentamente el número de veces del valor mínimo al valor máximo.

Debo haber pensado, por ejemplo, que podemos intercambiar las tres posiciones 1 3 5 antes

Primero intercambiamos 1 3 y luego intercambiamos 5 para expandir con éxito una vez

Siempre que se pueda construir de acuerdo con esto.

Consideramos comenzar con el último conjunto de intercambios. De hecho, también podemos comenzar con el primer intercambio, pero esto es más complicado de escribir.

Luego, solo saque el último fragmento del grupo más pequeño original y cámbielo a uno nuevo. Si resulta que un grupo se ha ido, vaya al grupo anterior.

#include <iostream> 
#include <algorithm> 
#include <cstring> 
#include <cstdio> 
#include <map> 
#include < string > 
#include <vector>
 usando el  espacio de nombres std; 
typedef vector < int > VI;
const  int N = 3000010 ;
int n, k;
cuerda s;
int tot, idx, cnt; 
vector < int > ans [N];
int main () { 
    cin >> n >>  k;
    cin>> s;
    int i, j;
    while ( 1 ) {
         for (i = 0 ; i <( int ) s.size () - 1 ; i ++ ) {
             if (s [i] == ' R ' && s [i + 1 ] == ' L ' ) { 
                ans [idx] .push_back (i); 
                cnt ++ ; 
            } 
        } 
        if (ans [idx] .empty ())
             break ;
        if (idx> = k) { 
            cout<<" -1 " << endl;
            devuelve  0 ; 
        } 
        idx ++ ;
        for (auto x: ans [idx- 1 ]) { 
            swap (s [x], s [x + 1 ]); 
        } 
    } 
    if (k> cnt) { 
        cout << - 1 << endl;
        devuelve  0 ; 
    } 
    int m = idx- 1 ;
    para (i = k- 1 ; i> = 0 ; i-- ) {
         if(ans [m] .empty ()) 
            m - ;
        if (! ans [i] .empty ()) se
             rompe ; 
        ans [i] .push_back (ans [m] .back ()); 
        ans [m] .pop_back (); 
    } 
    para (i = 0 ; i <k; i ++ ) { 
        printf ( " % d \ n " , ( int ) ans [i] .size ());
        para (auto x: ans [i]) { 
            printf ( " % d " , x + 1 ); 
        } 
        printf ( " \ n " ); 
    } 
    volver 0 ; 
}
Ver código

 

Supongo que te gusta

Origin www.cnblogs.com/ctyakwf/p/12718824.html
Recomendado
Clasificación