[R50C]截断加法
数据规模:,,,保证 。
思路
题目要找最小的非负整数 ,使得令 后,至少 个位置满足 。
先刻画单个位置 在什么 下能达标。因为 :
- 若 ,则 恒成立,该位置永远无法达标,无论 多大;
- 若 ,则 等价于 (因为此时 取到 这一侧即足够),即 。再与 取下界,得到该位置达标所需的最小非负 为 。
于是问题转化为:每个「可达标位置」()对应一个阈值 ,要选最小的 使至少 个阈值 。这等价于把所有阈值排序后取第 小的值——选它作为 时,恰有至少 个阈值不超过它,且再小就会有不足 个。
边界:若可达标位置总数不足 ,无解,输出 -1。
复杂度
时间 (排序主导),空间 。
仓颉实现
import std.collection.*
import std.convert.*
import std.env.*
import std.sort.*
main(): Int64 {
let reader = getStdIn()
let hdr = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let n = hdr[0]
let D = hdr[1]
let k = hdr[2]
let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let b = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
var needs = ArrayList<Int64>(0)
var i = 0
while (i < n) {
if (b[i] <= D) {
var need = b[i] - a[i]
if (need < 0) {
need = 0
}
needs.add(need)
}
i++
}
if (Int64(needs.size) < k) {
println("-1")
return 0
}
sort(needs)
println("${needs[k - 1]}")
return 0
}