Fácil–medio · casos límite
El segundo mayor
Encontrar el mayor ya sabes hacerlo. El segundo mayor es el mismo problema con una variable más, y una trampa: ¿qué pasa si todos los números son iguales?
En una fraseRecorre una sola vez guardando el mayor y el segundo mayor distinto; si todos los elementos son iguales no hay segundo mayor y la respuesta es la palabra none.
El problema
Entrada: La primera línea es un entero n (2 ≤ n ≤ 1000). La segunda línea contiene n enteros separados por espacios (−1000 ≤ ai ≤ 1000).
Salida: El segundo valor distinto más grande. Si todos los números son iguales, imprime none.
Ejemplos:
| Entrada | Salida |
|---|---|
5 | 7 |
4 | none |
3 | -5 |
Toda la dificultad está en "distinto". Con 3 9 2 9 7 la respuesta es 7, no 9: el 9 aparece dos veces pero sigue siendo un solo valor.
Tu solución
Entrada personalizada para «Ejecutar mi entrada»
La corrección corre en tu navegador contra pruebas ocultas. Un bucle infinito se corta a los 3 segundos — aun así, asegúrate de que todo bucle tenga salida. Tu código se guarda solo mientras escribes.
¿Atascado? Pistas
Pista 1 — Parte del máximo que ya conoces
Una variable big guarda el mayor visto hasta ahora. Añade otra, second. Cada vez que un número supera a big, el antiguo big desciende a second: esa línea es todo el truco.
Pista 2 — Dos ramas, no una
Si x > big, desplaza. Si no, si x es menor que big pero mayor que second, pasa a ser el nuevo second. Esa segunda rama hace inofensivos los duplicados: cuando x == big no se ejecuta ninguna, así que un máximo repetido nunca pisa al segundo.
Pista 3 — ¿Con qué valor empiezan las dos variables?
No 0. Las entradas pueden ser negativas, así que 0 parecería un "mayor" válido que nunca existió. Usa un valor por debajo de cualquier entrada legal, -1000000000, y al final comprueba si second sigue siendo ese centinela: si lo es, no había un segundo valor distinto.
Solución (¡inténtalo primero!)
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int big = -1000000000, second = -1000000000;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x > big) {
second = big;
big = x;
} else if (x < big && x > second) {
second = x;
}
}
if (second == -1000000000) cout << "none" << endl;
else cout << second << endl;
return 0;
}
Fíjate en lo que no hiciste: no guardaste nada, no ordenaste nada. Un recorrido, dos variables, listo: O(n) de tiempo y O(1) de memoria. La misma forma de desplazar te da el tercer mayor, los dos menores o las dos mejores puntuaciones de un juego. Ahora lleva esa memoria O(1) a un problema donde el array sí hay que reordenarlo: Ordenamiento burbuja.
Análisis profundo
Por qué funciona
Un recorrido, dos variables y listo: sin array, sin ordenar. Esa forma de desplazar valores es el esqueleto de todos los problemas Top-K que encuentres.
El coste
O(n) de tiempo y O(1) de memoria. Ordenar primero y tomar el segundo es O(n log n) más una copia de los datos: extender toda la baraja para leer una carta.
Dónde falla
- Empezar
seconden 0 imprime 0 con entradas todas negativas: una respuesta que no existe en los datos. - Escribir solo la rama
x > bigy olvidarx < big && x > seconddejasecondclavado en el máximo anterior cuando hay valores repetidos.
Siguiente paso
Ahora deja que una regla se ejecute sola y mira dónde acaba: Pasos de Collatz.
Dos cosas para recordar
- Dos variables y un descenso: cuando el nuevo rey sube al trono, el viejo pasa a segundo.
- El centinela debe ser menor que cualquier entrada legal, o se hará pasar por respuesta.
🐞 Esta versión falla: ábrela y pruébala
second empieza en 0: con entradas negativas imprime 0
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int big = 0, second = 0; // assumes the input is positive
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x > big) {
second = big;
big = x;
} else if (x < big && x > second) {
second = x;
}
}
cout << second << endl;
return 0;
}