原题链接
- 题意:给出 (n <= 1e5) 个点在二维平面的坐标,并且给出每个点的运动方向,点不会停止,会一直运动下去,速度为1m/s,然后求过了多少时间,((X_{max}-X_{min})*(Y_{max}-Y_{min})) 的值最小。
- 题解:想到了可能是一个凹函数,但是没想到用三分就做了,还一直死磕规律。
- 代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <cstring>
#include <map>
using namespace std;
const int N = 2e5 + 99;
typedef long long ll;
const ll mod = 1000000007;
const int inf = 0x3f3f3f3f;
struct node {
string op;
double x, y;
}a[N];
int n;
double sum(double t) {
double maxX, minX, maxY, minY;
for (int i = 1; i <= n; i++) {
double x = a[i].x;
double y = a[i].y;
if (a[i].op == "R")x += t;
if (a[i].op == "L")x -= t;
if (a[i].op == "U")y += t;
if (a[i].op == "D")y -= t;
if (i == 1) {
maxX = x;
minX = x;
maxY =y;
minY = y;
}
else {
minX = min(x, minX);
minY = min(y, minY);
maxX = max(x, maxX);
maxY = max(y, maxY);
}
}
//printf("%.10lf %.10lf
", l, r);
return (maxX - minX) * (maxY - minY);
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].y;
cin >> a[i].op;
}
double l = 0, r = 999999999999.9;
int TT = 75;
while (TT--) {
double lmid = (l + (r - l) / 3);
double rmid = (l + (r - l) * 2 /3);
if (sum(lmid) < sum(rmid)) r = rmid;
else l = lmid;
//printf("%.10lf %.10lf
", l, r);
}
printf("%.14lf
", sum(l));
// << endl;
}
signed main() {
ios::sync_with_stdio(0);
//init();
ll t = 1;//cin >> t;
while (t--)solve();
return 0;
}