题目链接

题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点。输出面积。

思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变。

正方形从0度到180度变化的过程中,把所有点覆盖,面积肯定是有一个最小峰值,是一个凸函数。因此可以用三分法解决。这里有一个难点就是已知两个定点的x,y坐标,过这两个点做两条平行线,平行线并与x轴成d度的角,怎么算出两条平行线的距离。

d1 = fabs(cos(d)*(yi-yj)-sin(d)*(xi-xj));

d2 = fabs*(sin(d)*(yi-yj)+cos(d)*(xi-xj));

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #define eps 1e-9
 5 
 6 using namespace std;
 7 
 8 int T,n;
 9 int x[1000],y[1000];
10 
11 double calc(double d)
12 {
13     double dis1,dis2,dis;
14     dis = 0.0;
15     for(int i = 1 ; i < n ; i ++)
16     {
17         for(int j = i+1 ; j <= n ;  j++)
18         {
19             dis1 = fabs(cos(d)*(y[i]-y[j])-sin(d)*(x[i]-x[j]));
20             dis2 = fabs(sin(d)*(y[i]-y[j])+cos(d)*(x[i]-x[j]));
21             dis = max(dis,max(dis1,dis2) ) ;
22         }
23     }
24     return dis*dis;
25 }
26 int main()
27 {
28     double l,r,mid,midmid;
29     double s1,s2;
30     cin>>T;
31     for(int k = 0 ; k < T ; k++)
32     {
33         cin>>n;
34         for(int i = 1 ; i <= n ; i++)
35             cin>>x[i]>>y[i];
36         l = 0.0;
37         r = acos(-1.0)/2;
38         while(r-l >= eps)
39         {
40             mid = (l + r) / 2 ;
41             midmid = (mid + r) / 2 ;
42             s1 = calc(mid) ;
43             s2 = calc(midmid) ;
44             if(s1 < s2)
45                 r = midmid ;
46             else l = mid ;
47         }
48         printf("%.2lf\n",min(s1,s2));
49     }
50     return 0;
51 }
View Code

相关文章:

  • 2021-05-26
  • 2021-06-12
  • 2022-12-23
  • 2021-05-03
  • 2021-06-07
  • 2021-11-29
  • 2021-06-02
猜你喜欢
  • 2021-12-31
  • 2022-12-23
  • 2021-10-07
  • 2021-07-28
  • 2021-06-15
  • 2021-07-24
  • 2022-12-23
相关资源
相似解决方案