POJ 3301 三分
链接:
http://poj.org/problem?id=3301
题意:
给定二维平面的n个点,要求一个面积最小的正方形,使其能覆盖所有的点。
题解:
我们可以让正方形不要动,所有点进行旋转变换,这样结果是不会变的。
变形即: x1=x*cos(a)-y*sin(a); y1=x*sin(a)+y*cos(a)
可以证明它们都是凸性函数,故他们差的最大值也是凸性函数,故可以用三分法,对旋转角度进行三分,求出最小的满足要求的正方形。
代码:
31 const double PI = acos(-1); 32 const double EPS = 1e-12; 33 double x[50], y[50]; 34 int n; 35 36 double calc(double a) { 37 double minx = 1e20, miny = 1e20, maxx = -1e20, maxy = -1e20; 38 rep(i, 0, n) { 39 double xx = x[i] * cos(a) - y[i] * sin(a); 40 double yy = x[i] * sin(a) + y[i] * cos(a); 41 minx = min(minx, xx); 42 maxx = max(maxx, xx); 43 miny = min(miny, yy); 44 maxy = max(maxy, yy); 45 } 46 return max(maxx - minx, maxy - miny); 47 } 48 49 int main() { 50 int T; 51 cin >> T; 52 while (T--) { 53 cin >> n; 54 rep(i, 0, n) cin >> x[i] >> y[i]; 55 double l = 0, r = PI, ans; 56 while (r - l > EPS) { 57 double m = (l + r) / 2; 58 double mm = (m + r) / 2; 59 ans = calc(m); 60 if (ans <= calc(mm)) r = mm; 61 else l = m; 62 } 63 printf("%.2f\n", ans*ans); 64 } 65 return 0; 66 }