Introducción
Usted es el jefe de policía de la policía de Nueva York y se le ha encomendado la tarea de posicionar a los oficiales de policía para que todas las calles estén patrulladas. Sin embargo, su escuadrón tiene poco personal, lo que significa que necesita posicionar la menor cantidad de oficiales posible.
Desafío
Dado un mapa de bloques, debe devolver el menor número de oficiales necesarios para asegurar las calles.
Reglas
Hay tres tipos de oficiales de policía: un policía L, un policía T y un policía cruzado. El policía T solo puede ver en tres direcciones. El policía L puede ver dos calles que son perpendiculares. El policía cruzado puede ver las cuatro calles.
El mapa se proporcionará a través de argv o STDIN como números separados por espacios. Los números representan el número de bloques en cada columna. Por ejemplo:
La entrada 2 1
representa el siguiente mapa:
La entrada 3 1 2 4
representa el siguiente mapa:
Un oficial de policía solo puede ser ubicado en una intersección y su vista solo puede ser a lo largo del costado de una cuadra (los policías no pueden mirar hacia áreas deshabitadas).
Un policía solo puede ver una cuadra y no puede mirar a lo largo de una calle donde está mirando otro oficial de policía, lo que significa que las líneas de visión no deben superponerse.
Ejemplos
Entrada: 2 1
Salida: 4
Entrada: 2 2
Salida: 4
Entrada: 3 1 4 1 5 9
Salida: 22
Victorioso
El código más corto gana.
Respuestas:
CJam,
68 61 84 ... 59 49 4879 bytesToma la entrada en el mismo formato que en cuestión.
ACTUALIZACIÓN : Se corrigió el algoritmo para casos de prueba similar a lo que señaló @nutki. Aunque hizo que el código tuviera casi el doble de tamaño, intentará jugarlo ahora que está solucionado.
Cómo funciona (Ligeramente incompleto, agregará la
2 1 2
explicación de paridad más adelante)Tan pronto como vi esta pregunta, supe que habría una fórmula matemática para obtener la respuesta. Después de probar un par de combinaciones, pensé que la fórmula es
2 * Number of blocks - Number of shared streets
Vamos a comprobar es por
2 1
caso:Correcto.
Vamos a ver por
3 1 2 4
caso:Corregir de nuevo. Sí, entonces el código es
Ahora intentemos esto con algunos ejemplos más:
Salida:
Pero espera, la respuesta real es 6
Probemos otro:
¿Ves el patrón?
Para cada
N N
par de bloques, donde N es un número entero positivo mayor que2
, requierofloat((N+1)/2)-1
más policía aparte de la fórmula anterior. Vamos a verificarlo de nuevo:En el ejemplo anterior, tenemos 1
5 5
par y 13 3
par (de los5 3
bloques)Probemos otro ejemplo
Usted debe estar pensando que sólo hay
5 5
,3 3
y3 3
los pares (a partir de bloques5 5
,5 4
y4 4
resp.), Por lo tanto, sólo 4 policías extra que sea necesario, pero hay un par más.De los bloques
4 4
, utilizamos solo3 3
para tener1 1
libre, esto constituye otro3 3
par de bloques que se puede visualizar usando la imagen a continuación:Los contorneados en rojo son los pares habituales, el contorneado en azul es el par perpendicular del que estoy hablando anteriormente.
Es un poco difícil de explicar, ya que mientras los contorneados rojos solo comparten 1 lado del par, el azul también comparte 1 lado + 1 bloque. Pero esta lógica funciona para todas las combinaciones de bloques.
El código ahora es simplemente calcular eso.
Tenga en cuenta que
2 * Number of blocks - Number of shared sides
también se puede escribir comoNumber of blocks + Number of columns - Number of shared sides between adjacant columns
Pruébalo en línea aquí
fuente
4 4 4 4
también La rutina da11
, pero no veo ninguna forma de hacerlo con menos de 12.2 2 1 1 2 2 1 2 2 1 1 2 2
mi ejemplo de contador para la solución @FireFly. Sin embargo, no puedo ver nada mejor que 19. ¿Puede mostrar la ubicación de este caso de prueba?