Caso # | Resultado | Tiempo | Memoria |
---|---|---|---|
#1 |
Correcto
|
0.025 s | 3 KBi |
#2 |
Correcto
|
0.027 s | 3 KBi |
#3 |
Correcto
|
0.028 s | 3 KBi |
#4 |
Correcto
|
0.028 s | 3 KBi |
#5 |
Correcto
|
0.025 s | 3 KBi |
#6 |
Correcto
|
0.026 s | 3 KBi |
#7 |
Correcto
|
0.024 s | 3 KBi |
#8 |
Correcto
|
0.028 s | 3 KBi |
#9 |
Correcto
|
0.026 s | 3 KBi |
#10 |
Correcto
|
0.023 s | 3 KBi |
#11 |
Correcto
|
0.025 s | 4 KBi |
#12 |
Correcto
|
0.026 s | 3 KBi |
#13 |
Correcto
|
0.027 s | 5 KBi |
#14 |
Correcto
|
0.026 s | 3 KBi |
#15 |
Correcto
|
0.03 s | 3 KBi |
#16 |
Correcto
|
0.035 s | 3 KBi |
#17 |
Correcto
|
0.032 s | 3 KBi |
#18 |
Correcto
|
0.034 s | 3 KBi |
#19 |
Correcto
|
0.033 s | 3 KBi |
#20 |
Correcto
|
0.039 s | 3 KBi |
# Ya que Andrés pasó por mi código explicando # la solución en el último stream, aquí está # una versión más comentada del mismo algoritmo # 1. Leyendo la entrada: mat_size = int(input()) # 1.1. Para leer la matriz hay que # (1) leer cada línea de la matriz y # (2) para cada caracter en una línea, # convertir este a entero. Aquí aprovechamos # dos formas de iterar sobre listas: el # list-comprehension y la función map (como # mencionaba Andrés, esta línea tiene # complejidad N**2) mat = [list(map(int, input().split())) for _ in range(mat_size)] # 2. Estrategia: pasar una vez por cada # elemento de la matriz y establecer a qué # fila pertenece, a qué columna pertenece y # si pertenece a alguna de las 2 diagonales. # Todas esas consultas pueden hacerse con los # índices de la matriz. # 2.1. Los resultados de cada consulta van a # acumularse, uno por cada fila, columna y # diagonal. Una forma simple de modelar estos # valores es con un arreglo donde los # primeros 'mat_size' elementos (llamado N en # la definición del problema) corresponden a # la suma de las filas, los siguientes # 'mat_size' elementos, corresponden a la # suma de las columnas y los últimos dos, a # la de las 2 diagonales. accums = [0] * (mat_size * 2 + 2) # 2.2. Recorrer la matriz usando un doble # bucle normal for i, row in enumerate(mat): for j, elem in enumerate(row): # Acumula valor de la fila accums[i] += elem # Acumula valor de la columna accums[mat_size + j] += elem # Revisa si pertenece a la diagonal que # va de izquiera-derecha, arriba-abajo if i == j: accums[-1] += elem # Revisa si pertenece a la diagonal que # va de izquierda-derecha, abajo-arriba. # Es un error poner este IF como una # cláusula ELSE del primer IF porque, # cuando N es impar, el elemento del # medio en la matriz cuenta para las dos # diagonales if mat_size - 1 - j == i: accums[-2] += elem # 3. Verificar que todos los acumuladores # tienen el mismo valor. # 3.1. Valor de referencia x0 = accums[0] # 3.2. De nuevo usando map para hacer la # línea más compacta. El primer argumento del # 'map' es una versión funcional de un IF (de # ahí sale la expresión 'lambda' y retorna un # booleano). La función 'all' pasa de nuevo # por todos los valores booleanos y retorna # True si todos los elementos en la lista son # True (y False si al menos uno de ellos no # lo es). La complejidad es lineal respecto # al tamaño de 'accums', es decir O(2N+2+N) = # O(3N+2) = O(N) is_magic = all(map(lambda x: x == x0, accums)) # 4. Salida: Forma comprimida para imprimir # 'Yes' o 'No'. Tampoco suelo escribir así # (es más a manera de ejercicio). De hecho, # esto hace el código más lento que el IF # normal. print(['No', 'Yes'][int(is_magic)])