Se presentan N (3 ≤ N < 10000) atletas iedntificados por sus IDs de 0 a N-1, donde su habilidad se representa mediante un conjunto de enteros. Estos compiten entre sí para determinar el primer, segundo y tercer lugar. Las reglas establecen que el atleta 0 se enfrenta al 1, el 2 al 3, y así sucesivamente. En cada ronda, los atletas adyacentes compiten, ganando el que tenga mayor habilidad; si hay un empate, gana el atleta con el ID menor. Los atletas que no tienen oponente pasan directamente a la siguiente ronda.
Entrada: Una línea con N números enteros representando las habilidades de los atletas (0 ≤ habilidad ≤ 10000000000).
Salida: Los IDs del primer, segundo y tercer lugar, separados por espacios.
| Entrada | Salida |
|---|---|
| 2 3 4 5 | 3 1 2 |
Explicación: En la primera ronda, el atleta 0 (habilidad 2) se enfrenta al 1 (habilidad 3); gana el 1. El atleta 2 (habilidad 4) se enfrenta al 3 (habilidad 5); gana el 3. En la ronda final, el 3 se enfrenta al 1; gana el 3. Para el tercer lugar, compiten el 2 y el 0; gana el 2.
El problema requiere un análisis lógico cuidadoso. Dado que cada ronda reduce a la mitad el número de atletas, es manejable incluso con grandes cantidades. Se utiliza una lista enlazada para almacenar los grupos de ganadores y perdedores de cada ronda, asegurándose de que los ganadores estén siempre al inicio.
A continuación, se muestran implementaciones en Java, JavaScript y Python.
Implementación en Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
public class Campeonato {
static class Atleta {
int id;
long habilidad;
Atleta(int id, long habilidad) {
this.id = id;
this.habilidad = habilidad;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long[] habilidades = Arrays.stream(scanner.nextLine().split(" "))
.mapToLong(Long::parseLong)
.toArray();
System.out.println(determinarGanadores(habilidades));
}
static String determinarGanadores(long[] habilidades) {
LinkedList<ArrayList<Atleta>> resultados = new LinkedList<>();
ArrayList<Atleta> atletas = new ArrayList<>();
for (int i = 0; i < habilidades.length; i++) {
atletas.add(new Atleta(i, habilidades[i]));
}
avanzarRonda(atletas, resultados);
while (resultados.getFirst().size() > 1) {
avanzarRonda(resultados.removeFirst(), resultados);
}
int primero = resultados.get(0).get(0).id;
int segundo = resultados.get(1).get(0).id;
resultados.get(2).sort((a, b) -> Long.compare(b.habilidad, a.habilidad) == 0 ? Integer.compare(a.id, b.id) : Long.compare(b.habilidad, a.habilidad));
int tercero = resultados.get(2).get(0).id;
return primero + " " + segundo + " " + tercero;
}
static void avanzarRonda(ArrayList<Atleta> atletas, LinkedList<ArrayList<Atleta>> resultados) {
ArrayList<Atleta> ganadores = new ArrayList<>();
ArrayList<Atleta> perdedores = new ArrayList<>();
for (int i = 1; i < atletas.size(); i += 2) {
Atleta mayor = atletas.get(i);
Atleta menor = atletas.get(i - 1);
if (mayor.habilidad > menor.habilidad) {
ganadores.add(mayor);
perdedores.add(menor);
} else {
ganadores.add(menor);
perdedores.add(mayor);
}
}
if (atletas.size() % 2 != 0) {
ganadores.add(atletas.get(atletas.size() - 1));
}
resultados.addFirst(perdedores);
resultados.addFirst(ganadores);
while (resultados.size() > 3) {
resultados.removeLast();
}
}
}
Implementación en JavaScript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', (line) => {
const atletas = line.split(' ').map((valor, indice) => new Atleta(indice, parseInt(valor)));
console.log(determinarGanadores(atletas));
});
class Atleta {
constructor(id, habilidad) {
this.id = id;
this.habilidad = habilidad;
}
}
function determinarGanadores(atletas) {
const resultados = [];
avanzarRonda(atletas, resultados);
while (resultados[0].length > 1) {
avanzarRonda(resultados.shift(), resultados);
}
const primero = resultados[0][0].id;
const segundo = resultados[1][0].id;
resultados[2].sort((a, b) => b.habilidad === a.habilidad ? a.id - b.id : b.habilidad - a.habilidad);
const tercero = resultados[2][0].id;
return `${primero} ${segundo} ${tercero}`;
}
function avanzarRonda(atletas, resultados) {
const ganadores = [];
const perdedores = [];
for (let i = 1; i < atletas.length; i += 2) {
const mayor = atletas[i];
const menor = atletas[i - 1];
if (mayor.habilidad > menor.habilidad) {
ganadores.push(mayor);
perdedores.push(menor);
} else {
ganadores.push(menor);
perdedores.push(mayor);
}
}
if (atletas.length % 2 !== 0) {
ganadores.push(atletas[atletas.length - 1]);
}
resultados.unshift(perdedores);
resultados.unshift(ganadores);
while (resultados.length > 3) {
resultados.pop();
}
}
Implementación en Python
class Atleta:
def __init__(self, id, habilidad):
self.id = id
self.habilidad = habilidad
def determinar_ganadores(habilidades):
atletas = [Atleta(i, h) for i, h in enumerate(habilidades)]
resultados = []
avanzar_ronda(atletas, resultados)
while len(resultados[0]) > 1:
avanzar_ronda(resultados.pop(0), resultados)
primero = resultados[0][0].id
segundo = resultados[1][0].id
resultados[2].sort(key=lambda x: (-x.habilidad, x.id))
tercero = resultados[2][0].id
return f"{primero} {segundo} {tercero}"
def avanzar_ronda(atletas, resultados):
ganadores = []
perdedores = []
for i in range(1, len(atletas), 2):
mayor = atletas[i]
menor = atletas[i - 1]
if mayor.habilidad > menor.habilidad:
ganadores.append(mayor)
perdedores.append(menor)
else:
ganadores.append(menor)
perdedores.append(mayor)
if len(atletas) % 2 != 0:
ganadores.append(atletas[-1])
resultados.insert(0, perdedores)
resultados.insert(0, ganadores)
while len(resultados) > 3:
resultados.pop()
if __name__ == "__main__":
habilidades = list(map(int, input().split()))
print(determinar_ganadores(habilidades))