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
", ans*ans);
64     }
65     return 0;
66 }
原文地址:https://www.cnblogs.com/baocong/p/6761817.html