Introdução
Você é o chefe de polícia da polícia de Nova York e foi encarregado de posicionar policiais para que todas as ruas sejam patrulhadas. No entanto, seu esquadrão tem poucos funcionários, o que significa que você precisa posicionar o mínimo de oficiais possível.
Desafio
Dado um mapa de quarteirões, você deve devolver o menor número de policiais necessário para proteger as ruas.
Regras
Existem três tipos de policiais: um policial L, um policial T e um policial cruzado. O policial T pode ver apenas em três direções. O policial L pode ver abaixo duas ruas que são perpendiculares. O policial pode ver as quatro ruas abaixo.
O mapa será fornecido via argv ou STDIN como números separados por espaço. Os números representam o número de blocos em cada coluna. Por exemplo:
Entrada 2 1
representa o seguinte mapa:
Entrada 3 1 2 4
representa o seguinte mapa:
Um policial só pode ser colocado em um cruzamento e sua visão pode estar ao lado de um quarteirão (os policiais podem não olhar para áreas desabitadas).
Um policial pode ver apenas um quarteirão e não pode olhar ao longo de uma rua onde outro policial está olhando, o que significa que as linhas de visão não devem se sobrepor.
Exemplos
Entrada: 2 1
Resultado: 4
Entrada: 2 2
Resultado: 4
Entrada: 3 1 4 1 5 9
Resultado: 22
Ganhando
O código mais curto vence.
Respostas:
CJam,
68 61 84 ... 59 49 4879 bytesRecebe entrada no mesmo formato que em questão.
UPDATE : Corrigido o algoritmo para casos de teste semelhante ao indicado por @nutki. Embora tenha feito o código quase dobrar de tamanho, ele tentará jogar golfe agora que está consertado.
Como funciona (ligeiramente incompleto, adicionará a
2 1 2
explicação da paridade mais tarde)Assim que vi essa pergunta, soube que haveria uma fórmula matemática para obter a resposta. Depois de tentar algumas combinações, percebi que a fórmula é
2 * Number of blocks - Number of shared streets
Vamos verificar é o
2 1
caso:Corrigir.
Vamos verificar o
3 1 2 4
caso:Corrija novamente. Yipee, então o código é
Agora vamos tentar isso em mais alguns exemplos:
Resultado:
Mas espere, a resposta real é 6
Vamos tentar outra:
Você vê o padrão?
Para cada
N N
par de blocos, onde N é um número inteiro positivo maior que2
, eu exijofloat((N+1)/2)-1
um policial extra além da fórmula acima. Vamos verificar novamente:No exemplo acima, temos 1
5 5
par e 13 3
par (dos5 3
blocos)Vamos tentar outro exemplo
Você deve estar pensando que há somente
5 5
,3 3
e3 3
pares (de blocos5 5
,5 4
e4 4
resp.), Portanto, apenas 4 policiais extras necessários, mas há mais um par.A partir dos blocos
4 4
, usamos apenas3 3
para termos1 1
livre, isso constitui outro3 3
par de blocos que pode ser visualizado usando a imagem abaixo:O vermelho delineado são os pares usuais, o azul delineado é o par perpendicular do qual estou falando acima.
É meio difícil de explicar, enquanto o vermelho descrito está apenas compartilhando um lado do par, o azul está compartilhando um lado + 1 bloco também. Mas essa lógica funciona para todas as combinações de blocos.
O código agora está simplesmente calculando isso.
Observe que
2 * Number of blocks - Number of shared sides
também pode ser escrito comoNumber of blocks + Number of columns - Number of shared sides between adjacant columns
Experimente online aqui
fonte
4 4 4 4
também. A rotina dá11
, mas eu não consigo ver nenhuma maneira de fazê-lo com menos de 12.2 2 1 1 2 2 1 2 2 1 1 2 2
meu exemplo de contador para a solução @FireFly. No entanto, não consigo ver nada melhor que 19. Você pode mostrar o posicionamento para este caso de teste?