题意
平面上有n个点,每个点有一个点权v。你现在可以以原点为圆心放置一个圆,请问要使圆能覆盖到的点的权值和达到x,圆的半径至少为多少?
思路
最小值问题 先考虑下单调性
点的点权为正整数,如果圆的半径增加,那么能覆盖的点会增大,权值和增大,具有单调性,所以可以二分圆的半径。
对于check函数,需要判断在圆里的点的权值和。这里用的是点到原点的距离和半径的比较做的
Go代码
package main
import "fmt"
type MyPoint struct {
x, y, v int64
}
func main() {
var n int
var x int64
fmt.Scan(&n, &x)
points := make([]MyPoint, n+1)
for i := 1; i <= n; i++ {
fmt.Scan(&points[i].x, &points[i].y, &points[i].v)
}
var l, r, ans float64 = 0, 1e10, -1
const AUC = 0.000_001
check := func(r float64) bool {
var sum int64 = 0
for i := 1; i <= n; i++ {
var tmp int64 = points[i].x * points[i].x + points[i].y * points[i].y
if float64(tmp) <= r * r {
sum += points[i].v
}
}
return sum >= x
}
for l <= r {
mid := (l + r) / 2
if check(mid) {
ans = mid
r = mid - AUC
} else {
l = mid + AUC
}
}
fmt.Println(ans)
}

京公网安备 11010502036488号