Tarea
Se le dará un conjunto de círculos en el plano con sus centros en la línea y = 0 . Se garantiza que ningún par de círculos tiene más de un punto común.
Su tarea es determinar en cuántas regiones se dividen los círculos en el plano. Una región es un conjunto contiguo de puntos de inclusión máxima que no se cruza con ninguno de los círculos.
Debería escribir un programa que calcule esta respuesta cuando se le dé una descripción de los círculos.
Aquí hay un ejemplo:
En el lado izquierdo ves los círculos dibujados en el avión. Sin embargo, en la mitad derecha de la imagen, las regiones producidas por los círculos tienen un color distinto (un color por región). Hay seis regiones en este ejemplo.
Entrada
La primera línea de la entrada contiene un número N
, el número de descripciones de círculo a seguir. Esta línea es opcional, si su solución funciona sin ella, está bien.
N
Cada una de las siguientes líneas contiene dos enteros, x i y r i > 0 , que representan un círculo con centro (x i , 0) y radio r i .
Se garantiza que ningún par de círculos tiene más de un punto común. Además, se garantiza que x i y r i no exceden 10^9
en valor absoluto (por lo que caben cómodamente en un entero de 32 bits).
La entrada puede ser:
leer de STDIN
leer desde un archivo nombrado
I
en el directorio actual
Alternativamente, la entrada podría ser:
disponible como una cadena (incluidas las nuevas líneas) en una variable global
en la pila
Salida
Debe ser un número entero único, el número de regiones producidas. Esto debe escribirse en STDOUT o en un archivo nombrado O
en el directorio actual.
Reglas
El código más corto en bytes gana
Penalización de +200 bytes si su código no tiene un polinomio de tiempo de ejecución + complejidad espacial en
n
-Bono de 100 bytes para el peor tiempo de ejecución esperado + complejidad espacial
O(n log n)
-50 bono de bonificación para el peor tiempo de ejecución esperado + complejidad espacial
O(n)
-Bono de 100 bytes para tiempo de ejecución determinista + complejidad espacial
O(n)
Mientras evalúa el tiempo de ejecución:
Suponga que las tablas hash tienen
O(1)
tiempo de ejecución esperado para insertar, eliminar y buscar, independientemente de la secuencia de operaciones y los datos de entrada. Esto puede o no ser cierto, dependiendo de si la implementación utiliza la aleatorización.Suponga que el tipo de lenguaje de programación incorporado requiere
O(n log n)
tiempo determinista , donden
está el tamaño de la secuencia de entrada.Suponga que las operaciones aritméticas en números de entrada toman solo
O(1)
tiempo.No asuma que los números de entrada están unidos por una constante, aunque, por razones prácticas, lo están. Esto significa que los algoritmos como la clasificación por radix o la clasificación por conteo no son de tiempo lineal. En general, se deben evitar factores constantes muy grandes.
Ejemplos
Entrada:
2
1 3
5 1
Salida: 3
Entrada:
3
2 2
1 1
3 1
Salida: 5
4
7 5
-9 11
11 9
0 20
Entrada:
9
38 14
-60 40
73 19
0 100
98 2
-15 5
39 15
-38 62
94 2
Salida: 11
Consejos
Podemos usar la siguiente idea para una solución muy compacta. Vamos a intersecar el conjunto de círculos con el eje X e interpretar los puntos de intersección como nodos en un gráfico plano:
Cada círculo produce exactamente 2 aristas en este gráfico y hasta dos nodos. Podemos contar el número de nodos mediante el uso de una tabla hash para realizar un seguimiento del número total de bordes distintos izquierdo o derecho.
Entonces podemos usar la fórmula característica de Euler para calcular el número de caras de un dibujo del gráfico:
V - E + F - C = 1
F = E - V + C + 1
Para calcular C
el número de componentes conectados, podemos usar una búsqueda de profundidad primero .
Nota: Esta idea problemática está tomada de un concurso de programación croata reciente , pero no hagas trampa mirando los esquemas de la solución. :)
n log n
bonificación? Además, tengo una nueva solución conceptualmente nueva. ¿Debo publicar una nueva respuesta de reemplazar la anterior? (Preferiría la primera, en caso de que mi nueva solución no sea realmente correcta)Respuestas:
Mathematica,
125122 - 150 = -28 caracteresNo sé la complejidad de la función incorporada
ConnectedComponents
.Uso:
fuente
ConnectedComponents
tiene una complejidad lineal esperada en el peor de los casos, por lo que si hay componentes O (n), esto estaría bien. No entiendo Mathematica, así que no puedo decir si es O (n) en general y si califica para el bono -150. Creo que si. ¿Lo ejecuto con entrada en STDIN?Ruby -
312306285273269259 caracteresEsta respuesta ha sido reemplazada por mi otro enfoque que utiliza considerablemente menos caracteres y se ejecuta
O(n log n)
.De acuerdo, vamos. Para empezar, solo quería una implementación funcional, por lo que aún no está optimizada algorítmicamente. Ordeno los círculos de mayor a menor y construyo un árbol (los círculos incluidos en otros círculos son hijos de los más grandes). Ambas operaciones toman lo
O(n^2)
peor y loO(n log n)
mejor. Luego recorro el árbol para contar áreas. Si los hijos de un círculo llenan todo su diámetro, hay dos áreas nuevas; de lo contrario, solo hay una. Esta iteración tomaO(n)
. Por lo tanto, tengo una complejidad generalO(n^2)
y no califico para recompensa ni penalización.Este código espera que la entrada sin el número de círculos se almacene en una variable
s
:Versión sin golf (espera entrada en variable
string
):fuente
11
. Para el de tu comentario9
.10
y8
con mi versión sin golf, pero11
y9
con mi versión de golf actual: DRuby,
203183173133 - 100 = 33 caracteresAsí que aquí hay un enfoque diferente. Esta vez, clasifico los círculos por su punto más a la izquierda. Los círculos que se tocan en su punto más a la izquierda se ordenan de mayor a menor. Esto toma
O(n log n)
(bueno, Ruby usa la ordenación rápida, así que en realidad,O(n^2)
pero implementar la ordenación de combinación / montón probablemente esté fuera del alcance de este desafío). Luego repito esta lista, recordando todas las posiciones de la izquierda y la derecha de los círculos que he visitado. Esto me permite detectar si una serie de círculos se conecta a través de un círculo más grande. En este caso, hay dos subáreas, de lo contrario, solo una. Esta iteración soloO(n)
da una complejidad total de laO(n log n)
cual califica para la recompensa de 100 caracteres.Este fragmento espera que la entrada se suministre a través de un archivo en los argumentos de la línea de comandos sin el número de círculos:
Versión sin golf (espera entrada en una variable
string
):fuente
-1 1 1 1 0 2 4 2 0 6
. Pensaré en cómo solucionar esto mañana por la noche (con suerte).Julia - 260 -100 (¿bonificación?) = 160
ACTUALIZACIÓN: Al pensar un momento, descubrí que el problema con mi método era solo cuando los círculos no estaban conectados, así que se me ocurrió una idea, ¿por qué no conectarlos artificialmente? Entonces el conjunto satisfará la fórmula de Euler.
F = 2 + EV (V = 6, E = 9)
[No trabaje con círculos anidados, por lo que no es una respuesta al problema para casos generales]
Código :
fuente
2 -10 1 10 1
.n=2
, los círculos son(C=(-10,0), r=1)
y(C=(10,0), r=1)
4 0 2 1 1 10 2 11 1
pero no creo que pueda darle muchos más casos de prueba, eso sería un poco injustoSpidermonkey JS,
308, 287, = 173Creo que si reescribiera esto en Ruby o Python podría salvar personajes.
Código:
Algoritmo:
No soy terriblemente bueno en la notación O grande, pero creo que es O (n) ya que estoy recorriendo cada círculo de manera efectiva 3 veces (crear, izquierda, derecha) y también ordenar las teclas del mapa (y ordenar por O ( n log n) pero eso desaparece). ¿Es esto determinista?
fuente
r
ciclo y ell
ciclo en una sola declaración, lo agradecería.JavaScript (ES6) -
255254 Caracteres -100250 Bonus =1554Asume que la cadena de entrada está en la variable
S
y genera el número de regiones en la consola.La complejidad temporal es ahora O (N).
Caso de prueba 1
Salidas:
3
Caso de prueba 2
Salidas:
5
Caso de prueba 3
Salidas:
6
Caso de prueba 4
Salidas:
11
Caso de prueba 5
Salidas:
105
Versión previa
Con comentarios:
La complejidad de tiempo total es O (N) para todo excepto el tipo que es O (N.log (N)); sin embargo, al reemplazar esto con un tipo de depósito, esto reducirá la complejidad total a O (N).
La memoria requerida es O (N).
Adivina lo que sigue en mi lista de tareas pendientes ... clasifica en menos de 150 caracteres.Hechofuente
O(n)
(de hechoO(n+k)
), peroO(n^2)
oO(n log n)
peor de los casos, dependiendo del algoritmo de ordenación utilizado dentro de baldes, por lo que había necesidad de hacerlo en 50 caracteres.