https://coderun.yandex.ru/problem/microwave Сложная

Решение

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.PriorityQueue

fun gcd(x: Long, y: Long): Long {
    var a = x
    var b = y
    while (b != 0L) {
        val t = b
        b = a % b
        a = t
    }
    return a
}

data class Node(val v: Int, val d: Long) : Comparable<Node> {
    override fun compareTo(other: Node) = d.compareTo(other.d)
}

fun main() {
    val reader = BufferedReader(InputStreamReader(System.`in`))
    val writer = BufferedWriter(OutputStreamWriter(System.out))

    val N = reader.readLine().toLong()
    val parts = reader.readLine().split(" ")
    val A = parts[0].toLong()
    val B = parts[1].toLong()
    val C = parts[2].toLong()

    val g = gcd(gcd(A, B), C)
    val Np = (N - 1) / g

    val a1 = A / g
    val b1 = B / g
    val c1 = C / g
    val coins = listOf(a1, b1, c1).sorted()
    val a = coins[0]
    val b = coins[1]
    val c = coins[2]

    val aInt = a.toInt()
    val modb = (b % a).toInt()
    val modc = (c % a).toInt()

    val dist = LongArray(aInt) { Long.MAX_VALUE }
    dist[0] = 0L
    val pq = PriorityQueue<Node>()
    pq.add(Node(0, 0L))

    while (pq.isNotEmpty()) {
        val node = pq.poll()
        val u = node.v
        val du = node.d
        if (du != dist[u]) continue

        // relax edge +b
        var v = u + modb
        if (v >= aInt) v -= aInt
        var nd = du + b
        if (nd < dist[v]) {
            dist[v] = nd
            pq.add(Node(v, nd))
        }

        // relax edge +c
        v = u + modc
        if (v >= aInt) v -= aInt
        nd = du + c
        if (nd < dist[v]) {
            dist[v] = nd
            pq.add(Node(v, nd))
        }
    }

    var total = 0L
    for (r in 0 until aInt) {
        val dr = dist[r]
        if (dr > Np) continue
        total += ((Np - dr) / a + 1)
    }

    writer.write(total.toString())
    writer.newLine()
    writer.flush()
    reader.close()
    writer.close()
}