题目大意
按逆时针给出凸包上的个点,你要在凸包里面找到一个点,让的最小值最大,然后输出这个最大的最小值。
Solution
考点:三分
比较明显的容易发现如果我们固定,那么的相关函数一定是一个单峰函数。
同理固定,那么的相关函数也一定是单峰函数。
那么就直接用三分套三分就可以求解了,复杂度。
const int INF = 0x3f3f3f3f; const int N = 100 + 7; const double PI = acos(-1); ll n, m; pai p[N]; double xmax = -INF, xmin = INF, ymax = -INF, ymin = INF; pai operator - (const pai& a, const pai& b) { return { a.first - b.first,a.second - b.second }; } double operator * (const pai& a, const pai& b) { return a.first * b.first + a.second * b.second; } double getLen(pai a) { return sqrt(a * a); } double getAngle(pai a, pai b) { return acos(a * b / getLen(a) / getLen(b)); } double check(pai x) { double res = INF; for (int i = 1; i <= n; ++i) { res = min(res, getAngle(p[i] - x, p[i + 1] - x)); } return res; } double calc(double x) { double l = ymin, r = ymax; for (int i = 1; i <= 100; ++i) { double lmid = l + (r - l) / 3.0; double rmid = r - (r - l) / 3.0; if (check({ x,lmid }) > check({ x,rmid })) { r = rmid; } else { l = lmid; } } return check({ x,l }); } int solve() { n = read(); for (int i = 1; i <= n; ++i) { auto& [x, y] = p[i]; x = read(), y = read(); xmax = max(xmax, x); xmin = min(xmin, x); ymax = max(ymax, y); ymin = min(ymin, y); } p[n + 1] = p[1]; double l = xmin, r = xmax; for (int i = 1; i <= 100; ++i) { double lmid = l + (r - l) / 3.0; double rmid = r - (r - l) / 3.0; if (calc(lmid) > calc(rmid)) { r = rmid; } else { l = lmid; } } printf("%.12f\n", calc(l) * 180 / PI); return 1; }