题意
平面上有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) }