C++: ¿cómo solucionar este problema? Casi lo consigo, sólo que me quedé un poco atascado.

programación


Estaba solucionando problemas de C++ hasta que encontré este, que simplemente no pude resolver después de mucho tiempo (ni siquiera pude pasar la muestra). ¡Por favor ayuda!

El granjero John tiene una tarea importante: averiguar qué tipo de heno comprar para sus vacas.
Las N vacas del granjero John (2≤N≤10^5) están numeradas del 1 al N y a cada vaca le gusta exactamente un tipo de heno h(i): (1≤h(i)≤N. Quiere que a todas sus vacas les guste el mismo tipo de heno.
Para que esto suceda, Farmer John puede organizar grupos focales. Un grupo focal consiste en reunir a todas las vacas en un rango contiguo numerado ito j, inclusive, para una reunión. Si hay un tipo de heno que le gusta a más de la mitad de las vacas del grupo, luego de que el grupo focal termina de reunirse, a todas las vacas les termina gustando ese tipo de heno. Si no existe tal tipo de heno, entonces ninguna vaca cambia el tipo de heno que le gusta. Por ejemplo, en un grupo focal que consta de un rango de 16 vacas, 9 o más de ellas necesitarían tener la misma preferencia de heno para que las vacas restantes cambien su preferencia para igualar.
El granjero John quiere saber qué tipos de heno pueden gustar a todas las vacas al mismo tiempo. Solo puede albergar un grupo focal a la vez, pero puede dirigir tantos grupos focales como sea necesario para lograr que a todas las vacas les guste el mismo tipo de heno.

FORMATO DE ENTRADA:
El primero constará de un número entero T, que denota el número de casos de prueba independientes (1≤T≤10)

La primera línea de cada caso de prueba consta de N.
La segunda línea consta de N números enteros, los tipos de heno favoritos h(i) para las vacas en orden.
Se garantiza que la suma de N en todos los casos de prueba no exceda 2⋅10^5.

FORMATO DE SALIDA:
Líneas T de salida, una línea por caso de prueba.
Si es posible hacer que a todas las vacas les guste el mismo tipo de heno simultáneamente, produzca todos los tipos posibles de heno en orden creciente. De lo contrario, genere −1. Al imprimir una lista de números en la misma línea, separe los números adyacentes con un espacio y asegúrese de que la línea no termine con espacios superfluos.

ENTRADA DE MUESTRA:
5
5
1 2 2 2 3
6
1 2 3 1 2 3
6
1 1 1 2 2 2
3
3 2 3
2
2 1
SALIDA DE MUESTRA:
2
-1
1 2
3
-1
En la entrada de muestra, hay 5 casos de prueba.
En el primer caso de prueba, sólo es posible hacer que todas las vacas sean del tipo 2. FJ puede hacerlo ejecutando un único grupo focal con todas las vacas.
En el segundo caso de prueba, podemos demostrar que ninguna vaca cambiará el tipo de heno que le gusta.
En el tercer caso de prueba, es posible hacer que todas las vacas sean del tipo 1 organizando tres grupos focales: primero, teniendo las vacas 1 a 4 en un grupo focal, luego teniendo las vacas 1 a 5 en un grupo focal, luego teniendo vacas 1 a 6 en un grupo focal. Siguiendo una lógica similar, usando las vacas 3 a 6, las vacas 2 a 6, luego las vacas 1 a 6, podemos hacer que todas las vacas sean como el tipo 2.
En el cuarto caso de prueba, es posible hacer que todas las vacas sean del tipo 3 ejecutando un único grupo focal con todas las vacas.
En el quinto caso de prueba, podemos demostrar que ninguna vaca cambiará el tipo de heno que prefiere.

PUNTUACIÓN:

* Entrada 2: N=2.
* Entradas 3-4: N≤50.
* Entradas 5-6: h(i)≤h(i+1) para todos los 1≤i≤N−1.
* Entradas 7-15: Sin restricciones adicionales.

Lo que he probado:

He elaborado el siguiente código (que incluso hace que la última línea de salida de E/S de muestra sea incorrecta):

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

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

    int T;
    cin >> T;
    while(T--) {
        int N;
        cin >> N;
        vector<int> h(N);
        for(int i=0; i<N; i++) {
            cin >> h[i];
        }

        map<int, int> count;
        for(int i=0; i<N; i++) {
            count[h[i]]++;
        }

        vector<int> possible;
        for(auto &p : count) {
            if(p.second > N/2) {
                possible.push_back(p.first);
            }
        }

        if(possible.empty()) {
            // Check for types of hay liked by exactly half the cows
            for(auto &p : count) {
                if(p.second == N/2) {
                    possible.push_back(p.first);
                }
            }
        }

        if(possible.empty()) {
            cout << -1 << "\n";
        } else {
            sort(possible.begin(), possible.end());
            for(int i=0; i<possible.size(); i++) {
                cout << possible[i] << (i == possible.size()-1 ? "\n" : " ");
            }
        }
    }

    return 0;
}

Si alguien tiene alguna solución o cambio en el código que pueda resolver la pregunta, ¡dímelo! ¡Muchas gracias a todos!

Solución 1

¡Compilar no significa que tu código sea correcto! :reír:
Piense en el proceso de desarrollo como escribir un correo electrónico: compilar correctamente significa que escribió el correo electrónico en el idioma correcto (inglés, en lugar de alemán, por ejemplo), no que el correo electrónico contenía el mensaje que deseaba enviar.

Ahora ingresa a la segunda etapa de desarrollo (en realidad es la cuarta o quinta, pero llegará a las etapas anteriores más adelante): Prueba y depuración.

Empiece por observar lo que hace y en qué se diferencia de lo que quería. Esto es importante porque le brinda información de por qué lo está haciendo. Por ejemplo, si un programa está destinado a permitir al usuario ingresar un número y lo duplica e imprime la respuesta, entonces si la entrada/salida fue así:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16

Entonces es bastante obvio que el problema está en el bit que lo duplica: no se suma a sí mismo ni lo multiplica por 2, sino que lo multiplica por sí mismo y devuelve el cuadrado de la entrada.
Con eso, puedes mirar el código y es obvio que está en algún lugar aquí:

C++
int Double(int value)
   {
   return value * value;
   }

Una vez que tenga una idea de lo que podría estar fallando, comience a utilizar el depurador para descubrir el motivo. Coloque un punto de interrupción en la primera línea del método y ejecute su aplicación. Cuando llegue al punto de interrupción, el depurador se detendrá y le entregará el control. Ahora puede ejecutar su código línea por línea (llamado “paso único”) y ver (o incluso cambiar) el contenido de las variables según sea necesario (diablos, incluso puede cambiar el código e intentarlo nuevamente si es necesario).
Piensa en lo que debería hacer cada línea del código antes de ejecutarla y compáralo con lo que realmente hizo cuando usas el botón “Pasar por encima” para ejecutar cada línea por turno. ¿Hizo lo que esperabas? Si es así, pase a la siguiente línea.
¿Si no, porque no? ¿En qué se diferencia?
Con suerte, eso debería ayudarle a localizar qué parte de ese código tiene un problema y cuál es el problema.
Esta es una habilidad que vale la pena desarrollar, ya que le ayuda tanto en el mundo real como en el desarrollo. Y como todas las habilidades, ¡solo mejora con el uso!

コメント

タイトルとURLをコピーしました