Visión general
Dada una lista de fuegos artificiales a-z
y tiempos 3-78
, organícelos con fusibles para que todos se enciendan en el momento correcto.
Se da una línea de entrada como letras y números separados por espacios:
a 3 b 6 c 6 d 8 e 9 f 9
Ese ejemplo muestra que los fuegos artificiales a
deben encenderse a la vez 3
, b
y c
ambos en 6
, d
en 8
, con e
y f
ambos en 9
. Cada línea corresponde a un mapa.
La salida es un mapa de fusibles / fuegos artificiales para cada línea, que utiliza los símbolos |-
para mostrar fusibles y las letras para mostrar fuegos artificiales.
Un -
fusible se conecta a fusibles y fuegos artificiales directamente a la izquierda / derecha, mientras que un |
fusible se conecta con los de arriba / abajo. Por ejemplo, los fusibles no||
están conectados, y lo están .-|
Por ejemplo, dos posibles respuestas a las anteriores son:
---a ---------f
| ||| ||
|-c ||| de
--|--d a||
| b | |c
f e b
Todos los mapas de fusibles deben comenzar con un solo -
en la esquina superior izquierda. Ese es el punto donde enciende el fusible. Cada personaje de fusible tarda un segundo en quemarse. Como puede ver, a
se alcanza en tres segundos en ambos diagramas, b
en seis, etc.
Ahora, los dos mapas dados anteriormente son válidos para la entrada dada, pero uno es claramente más eficiente. El izquierdo solo usa 13 unidades de fusible, mientras que el derecho toma 20.
¡Los fusibles no se queman a través de los fuegos artificiales! Entonces, para la entrada a 3 b 5
, esto no es válido:
---a--b
Desafío
Su objetivo es minimizar la cantidad de fusible utilizado en todos los casos de prueba. La puntuación es muy simple, el total de unidades de fusible utilizadas.
Si no puede producir un mapa para un caso de prueba, ya sea un caso imposible o no, la puntuación para ese caso es la suma de todos los tiempos (41 para el ejemplo anterior).
En caso de empate, la puntuación se modifica para que ganen los mapas más compactos . El puntaje de desempate es el área del cuadro delimitador de cada mapa. Es decir, la longitud de la línea más larga multiplicada por el número de líneas. Para mapas "imposibles" este es el cuadrado del número más grande (81 para el ejemplo anterior).
En el caso de que las presentaciones empaten ambos métodos de puntuación, el empate va a la entrada / edición anterior.
Su programa debe ser determinista, para fines de verificación.
Casos de prueba
Hay 250 casos de prueba, ubicados aquí . Cada uno tiene entre 4 y 26 fuegos artificiales. El tiempo mínimo de fusible para un fuego artificial es 3. Los fuegos artificiales en cada caso se "ordenan" por tiempo y letra, lo b
que significa que nunca se encenderán antes a
.
Cuando publique, incluya su programa completo, su puntaje total y el mapa resultante para (al menos) el primer caso de prueba que figura en el archivo:
a 6 b 8 c 11 d 11 e 11 f 11 g 12 h 15 i 18 j 18 k 21 l 23 m 26 n 28 o 28 p 30 q 32 r 33 s 33 t 34
fuente
rand.nextInt(5)%4
, por lo tanto, 40% de probabilidad0
y 20% para cada uno1,2,3
.-+-
en lugar de---
no conectar automáticamente los fuegos artificiales arriba / abajo, todavía tiene que haber un|
arriba / abajo para conectarlo a un fuego artificial.-+-
en lugar de-|-
está bien como está.Respuestas:
C ++
Longitud total: 9059, Área total: 27469, Fallas: 13.
Nota: El puntaje incluye penalizaciones por falla.
Salida de muestra:
Salida completa: http://pastebin.com/raw.php?i=spBUidBV
¿No te encantan las soluciones de fuerza bruta? Esto es un poco más que un simple algoritmo de retroceso: nuestro trabajador incansable se mueve por el mapa, colocando fusibles y fuegos artificiales según sea necesario, mientras prueba todos los movimientos posibles en cualquier momento. Bueno, casi --- restringimos el conjunto de movimientos y abandonamos los estados no óptimos de manera temprana para que no tome un tiempo insoportable (y, en particular, para que termine). Se tiene especial cuidado de no crear ningún ciclo o no intencional caminos y no volver por donde vinimos, así que está garantizado que no visitemos el mismo estado dos veces. Aun así, encontrar una solución óptima puede llevar un tiempo, por lo que eventualmente renunciamos a optimizar una solución si lleva demasiado tiempo.
Este algoritmo todavía tiene algo de margen. Por un lado, se pueden encontrar mejores soluciones aumentando los
FRUSTRATION
parámetros. No hay cajeros automáticos de la competencia, pero estos números se pueden aumentar si y cuando ...Compilar con:
g++ fireworks.cpp -ofireworks -std=c++11 -pthread -O3
.Ejecutar con:
./fireworks
.Lee la entrada de STDIN y escribe la salida en STDOUT (posiblemente fuera de servicio).
Pitón
Longitud total: 17387, Área total: 62285, Fallas: 44.
Salida de muestra:
Salida completa: http://pastebin.com/raw.php?i=mgiqXCRK
Como referencia, aquí hay un enfoque mucho más simple. Intenta conectar los fuegos artificiales a una sola línea de fusibles principales, creando una forma de "escalera". Si un fuego artificial no puede conectarse directamente a la línea principal (lo que ocurre cuando dos o más fuegos artificiales se encienden al mismo tiempo), rastrea la línea principal buscando un punto en el que pueda ramificarse perpendicularmente hacia abajo o hacia la derecha (y falla si no existe tal punto.)
Como era de esperar, lo hace peor que el solucionador de fuerza bruta, pero no por un gran margen. Honestamente, esperaba que la diferencia fuera algo mayor.
Ejecutar con:
python fireworks.py
.fuente