pku 3301 Texas Trip 三分法 解题报告

来源:互联网 发布:朴素贝叶斯算法例题 编辑:程序博客网 时间:2024/04/30 12:20

 

3301 Texas Trip 解题报告

首次领教了三分法,对于二分、三分解决一些数学问题有了更加深刻的领悟。

题意:求最小面积的正方形,覆盖平面上给定的N个点

算法:三分逐步细分。标准正放正方形的比较好做只要找出minx,miny,maxx,maxy即可但是最小正方形不一定是标准正放,每个点对角度坐标表换的值,(   x = node[j].x * cos(angle) - node[j].y * sin(angle);y = node[j].y * cos(angle) + node[j].x * sin(angle);)然后求标准正放的最小正方形即可。

AC代码:

#include <math.h>

#include <stdio.h>

#define MAX 1000000000

#define MIN -1000000000

#define pi (asin(1.)*2)

struct Texas

{

     int x, y;

};

 

int main()

{

     freopen("1.txt", "r", stdin);

     int i, j, test, n;

    

     scanf("%d", &test);

    while (test--)

     {

             Texas node[31];

             scanf("%d", &n);

             for (i = 0; i < n; i++)

             {

                      scanf("%ld%ld", &node[i].x, &node[i].y);

             }

             int times = 40;

             double cumulative = pi / 6, angle = 0, minboundary = MAX, from = 0, boundary;

             double downx, downy, upx, upy, x, y;       

             while (times--)

             {

                      for (i = 0; i < 4; i++)    //角度初始为0,那么4次相加后,将超过90

                      {

                               downx = downy = MAX; upx = upy = MIN;

                               for (j = 0; j < n; j++)

                               {

                                        x = node[j].x * cos(angle) - node[j].y * sin(angle);

                                        y = node[j].y * cos(angle) + node[j].x * sin(angle);

                                        if (x < downx) downx = x;

                                        if (x > upx) upx = x;

                                        if (y < downy) downy = y;

                                        if (y > upy) upy = y;

                               }

                               boundary = (upx - downx) > (upy - downy) ? (upx - downx) : (upy - downy);

                               if (boundary < minboundary)

                               {

                                        minboundary = boundary;

                                        from = angle;

                               }

                               angle += cumulative;

                      }

                      //逐步细分

                      if (angle)

                      {

                               angle = from - cumulative;

                      }

                      //三分思想的应用

                      if (angle == 0 || angle == 3)

                      {

                               cumulative /= 3;

                      }

                      else

                      {

                               cumulative = cumulative * 2 / 3;

                      }

        }

             printf("%.2lf/n", minboundary * minboundary);

     }

     return 0;

}

 

 

原创粉丝点击