Visão geral
Dada uma lista de fogos de artifício a-z
e horários 3-78
, organize-os com fusíveis para que todos acendam na hora correta.
Uma linha de entrada é fornecida como letras e números separados por espaço:
a 3 b 6 c 6 d 8 e 9 f 9
Esse exemplo mostra que o fogo de artifício a
precisa acender no momento 3
, b
e c
ambos em 6
, d
em 8
, com e
e f
ambos em 9
. Cada linha corresponde a um mapa.
A saída é um mapa de fusíveis / fogos de artifício para cada linha, usando os símbolos |-
para mostrar os fusíveis e as letras para mostrar os fogos de artifício.
Um -
fusível se conecta a fusíveis e fogos de artifício diretamente à esquerda / direita dele, enquanto um |
fusível se conecta aos que estão acima / abaixo. Por exemplo, os fusíveis não||
estão conectados e estão .-|
Por exemplo, duas respostas possíveis para o acima são:
---a ---------f
| ||| ||
|-c ||| de
--|--d a||
| b | |c
f e b
Todos os mapas de fusíveis devem começar com um único -
no canto superior esquerdo. Esse é o ponto em que você acende o fusível. Cada caractere de fusível leva um segundo para queimar. Como você pode ver, a
é atingido em três segundos nos dois diagramas, b
em seis, etc.
Agora, os dois mapas fornecidos acima são válidos para a entrada fornecida, mas um é claramente mais eficiente. O esquerdo usa apenas 13 unidades de fusível, enquanto o direito leva 20.
Os fusíveis não queimam com fogos de artifício! Portanto, para entrada a 3 b 5
, isso não é válido:
---a--b
Desafio
Seu objetivo é minimizar a quantidade de fusível usada em todos os casos de teste. A pontuação é muito simples, o total de unidades de fusível usadas.
Se você não pode produzir um mapa para um caso de teste, seja um caso impossível ou não, a pontuação desse caso é a soma de todos os tempos (41 no exemplo acima).
No caso de empate, a pontuação é modificada para que os mapas mais compactos sejam vencidos. A pontuação de desempate é a área da caixa delimitadora de cada mapa. Ou seja, o comprimento da linha mais longa vezes o número de linhas. Para mapas "impossíveis", esse é o quadrado do maior número (81 no exemplo acima).
No caso de envios vincularem a ambos os métodos de pontuação, o empate vai para a entrada / edição anterior.
Seu programa deve ser determinístico, para fins de verificação.
Casos de teste
Existem 250 casos de teste, localizados aqui . Cada um tem entre 4 e 26 fogos de artifício. O tempo mínimo de fusível para um fogo de artifício é 3. Os fogos de artifício em cada caso são "classificados" por hora e letra, o que significa b
que nunca acenderá antes a
.
Ao postar, inclua seu programa completo, sua pontuação total e o mapa resultante (pelo menos) do primeiro caso de teste fornecido no arquivo:
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
fonte
rand.nextInt(5)%4
40% de chance0
e 20% para cada um1,2,3
.-+-
no lugar de---
não conectar automaticamente fogos de artifício acima / abaixo, ainda é preciso haver um|
acima / abaixo para conectá-lo a um fogo de artifício.-+-
no lugar de-|-
está bem como está.Respostas:
C ++
Comprimento total: 9059, Área total: 27469, Falhas: 13.
Nota: A pontuação inclui penalidades por falha.
Saída de amostra:
Saída completa: http://pastebin.com/raw.php?i=spBUidBV
Você não adora soluções de força bruta? Isso é um pouco mais do que um simples algoritmo de retorno: nosso trabalhador incansável se move pelo mapa, colocando fusíveis e fogos de artifício conforme necessário, enquanto testa todos os movimentos possíveis a qualquer momento. Bem, quase --- restringimos o conjunto de movimentos e abandonamos cedo os estados não ideais, para que não demore insuportavelmente longo (e, em particular, para que termine.) É necessário um cuidado especial para não criar ciclos ou intencionalmente caminhos e não voltar da mesma maneira que viemos, por isso é garantido que não visitemos o mesmo estado duas vezes. Mesmo assim, encontrar uma solução ideal pode demorar um pouco, por isso, desistimos de otimizar uma solução se demorar muito.
Este algoritmo ainda tem algum espaço livre. Por um lado, é possível encontrar melhores soluções aumentando os
FRUSTRATION
parâmetros. Não existe caixa eletrônico concorrente, mas esses números podem ser aumentados se e quando ...Compilar com:
g++ fireworks.cpp -ofireworks -std=c++11 -pthread -O3
.Corra com:
./fireworks
.Lê a entrada de STDIN e grava a saída em STDOUT (possivelmente fora de ordem.)
Pitão
Comprimento total: 17387, Área total: 62285, Falhas: 44.
Saída de amostra:
Saída completa: http://pastebin.com/raw.php?i=mgiqXCRK
Para referência, aqui está uma abordagem muito mais simples. Ele tenta conectar fogos de artifício a uma única linha de fusível principal, criando uma forma de "escada". Se um fogo de artifício não puder se conectar diretamente à linha principal (o que acontece quando dois ou mais fogos de artifício acendem ao mesmo tempo), ele rastreia a linha principal procurando um ponto em que possa se ramificar perpendicularmente para baixo ou para a direita (e falha se esse ponto não existe.)
Sem surpresa, ele é pior que o solucionador de força bruta, mas não por uma margem enorme . Honestamente, eu esperava que a diferença fosse um pouco maior.
Corra com:
python fireworks.py
.fonte