Advertisement
mikhail_dvorkin

GCJ 2020 E Kotlin solution

Apr 4th, 2020
801
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.96 KB | None | 0 0
  1. private fun solve(possible: String = "POSSIBLE", impossible: String = "IMPOSSIBLE"): String {
  2.     for (n in 2..50) { solve(n, 0, 0); solve(n, 1, 1); solve(n, 1, 2) }
  3.     val (n, trace) = readInts()
  4.     for (i in 1..n) for (j in 1..n) for (k in 1..n) {
  5.         if ((i == j) xor (i == k) || (n - 2) * i + j + k != trace) continue
  6.         val d0 = setOf(i, j).size - 1
  7.         val d1 = setOf(i, j, k).size - 1
  8.         val a = solve(n, d0, d1) ?: continue
  9.         val switch = IntArray(n) { -1 }
  10.         switch[0] = i
  11.         switch[d0] = j
  12.         switch[d1] = k
  13.         for (x in a.indices) if (switch[x] == -1) switch[x] = (1..n).first { it !in switch }
  14.         return possible + "\n" + a.joinToString("\n") { row -> row.joinToString(" ") { switch[it].toString() } }
  15.     }
  16.     return impossible
  17. }
  18.  
  19. private val memo = mutableMapOf<String, List<IntArray>?>()
  20.  
  21. private fun solve(n: Int, d0: Int, d1: Int): List<IntArray>? {
  22.     val code = "$n $d0 $d1"
  23.     if (code in memo) return memo[code]
  24.     val a = List(n) { IntArray(n) { -1 } }
  25.     a.indices.forEach { i -> a[i][i] = 0 }
  26.     a[0][0] = d0
  27.     a[1][1] = d1
  28.     memo[code] = if (d1 >= n) null else search(a)
  29.     return memo[code]
  30. }
  31.  
  32. private fun search(a: List<IntArray>, magic: Int = 3): List<IntArray>? {
  33.     val n = a.size
  34.     for (x in magic until n) for (y in magic until n) a[x][y] = (y - x + n) % n
  35.     for (x in magic until n - magic) {
  36.         a[0][x] = x - 1
  37.         a[x][0] = n + 1 - x
  38.         a[x][1] = n + 2 - x
  39.         a[x][2] = n - x
  40.     }
  41.     val p = List(n) { LongArray(n) { -1L } }
  42.     while (true) {
  43.         for (i in a.indices) for (j in a.indices) {
  44.             val v = a[i][j]
  45.             if (v == -1) continue
  46.             for (x in a.indices) {
  47.                 if (x != i) p[x][j] = p[x][j] and (1L shl v).inv()
  48.                 if (x != j) p[i][x] = p[i][x] and (1L shl v).inv()
  49.                 if (x != v) p[i][j] = p[i][j] and (1L shl x).inv()
  50.             }
  51.         }
  52.  
  53.         var improved = false
  54.         for (x in a.indices) {
  55.             for (y in a.indices) {
  56.                 var f = a.indices.filter { ((p[x][it] shr y) and 1) > 0 }
  57.                 if (f.isEmpty()) return null
  58.                 if (f.size == 1 && a[x][f.first()] == -1) {
  59.                     a[x][f.first()] = y
  60.                     improved = true
  61.                 }
  62.                 f = a.indices.filter { ((p[it][x] shr y) and 1) > 0 }
  63.                 if (f.isEmpty()) return null
  64.                 if (f.size == 1 && a[f.first()][x] == -1) {
  65.                     a[f.first()][x] = y
  66.                     improved = true
  67.                 }
  68.                 f = a.indices.filter { ((p[x][y] shr it) and 1) > 0 }
  69.                 if (f.isEmpty()) return null
  70.                 if (f.size == 1 && a[x][y] == -1) {
  71.                     a[x][y] = f.first()
  72.                     improved = true
  73.                 }
  74.             }
  75.         }
  76.         if (!improved) break
  77.     }
  78.  
  79.     for (i in a.indices) for (j in a.indices) {
  80.         if (a[i][j] >= 0) continue
  81.         for (v in a.indices) {
  82.             if (((p[i][j] shr v) and 1) == 0L) continue
  83.             val b = a.map { it.clone() }
  84.             b[i][j] = v
  85.             val res = search(b)
  86.             if (res != null) return res
  87.         }
  88.         return null
  89.     }
  90.     return a
  91. }
  92.  
  93. fun main() = repeat(readInt()) { println("Case #${it + 1}: ${solve()}") }
  94.  
  95. private fun readLn() = readLine()!!
  96. private fun readInt() = readLn().toInt()
  97. private fun readStrings() = readLn().split(" ")
  98. private fun readInts() = readStrings().map { it.toInt() }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement