[R80A] 染色


数据规模

1≤a,b≤n≤1001 \le a, b \le n \le 100。答案不超过 nn,用 64 位整数足够。

思路

左侧机器涂的是区间 [1,a][1, a],右侧机器涂的是区间 [n−b+1,n][n-b+1, n]。两段区间的交集长度为

t=max⁡(0,a+b−n),t = \max(0, a+b-n),

即当 a+b≤na+b \le n 时两段不重叠,t=0t = 0;否则重合 a+b−na+b-n 个方格。

把两台机器涂色的次数相加,得到 a+ba+b。其中恰好被一台机器涂色的方格被计了 11 次,被两台机器同时涂色的方格被计了 22 次。设恰好只被一台机器涂色的方格有 xx 个,则

x+2t=a+b,x + 2t = a+b,

所以

x=a+b−2max⁡(0,a+b−n).x = a+b - 2\max(0, a+b-n).

也可以用「nn 减去不计入答案的方格」来理解,等价写法是 n−∣a+b−n∣n - \lvert a+b-n \rvert。当 a+b≥na+b \ge n 时两段区间没有空隙,不计入答案的只有被两台机器同时涂色的 a+b−na+b-n 个;当 a+b≤na+b \le n 时两段区间不重叠,不计入答案的只有一台机器都没涂的 n−(a+b)n-(a+b) 个。两种情况恰好合并成 ∣a+b−n∣\lvert a+b-n \rvert。

复杂度

时间复杂度 O(1)O(1),空间复杂度 O(1)O(1)。

仓颉实现

import std.env.*
import std.convert.*

main() {
    let reader = getStdIn()
    let v = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
    let n = v[0]
    let a = v[1]
    let b = v[2]
    var t: Int64 = a + b - n
    if (t < 0) {
        t = 0
    }
    println(a + b - 2 * t)
}