poj 3301 Texas Trip 【坐标旋转】

poj 3301 Texas Trip 【坐标旋转】

 

http://acm.pku.edu.cn/JudgeOnline/problem?id=3301

 

【题目大意】

给你若干点,求把这些所有点包围起来的最小正方形的面积。

 

【提交情况】

Wa若干tle若干,没找到合适的步长,对浮点运算没有应用大于小于而是直接等于。

 

【解题思路】

当正方形不能旋转的时候,只需要找到最左、最右、最上、最下的点,然后找最长的作为边算三角形的面积即可。由于正方形可以旋转,所以通过旋转坐标起到旋转正方形的面积,每次旋转一定角度,0—90旋转后取得最小值,然后在最小值左右扩充一段,将步长缩小,在试验旋转,经过15次迭代后即可得到最后结果。

 

【AC的代码】

#include <iostream>

#include <cstdio>

#include <cmath>

#define MAX 1000000000

#define MIN -1000000000

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

using namespace std;

 

long x[50],y[50];

 

int main()

{

         long t,n,j,i;

         double stepLen,from,num,left,right,up,down;

         double nx,ny,border,minBorder,minA,a,getSin,getCos;

         scanf("%ld",&t);

         while(t--)

         {

                   scanf("%ld",&n);

                   for(j=0;j<n;j++) scanf("%ld%ld",&x[j],&y[j]);

                   from=0; num=15; minBorder=MAX; stepLen=PI/18; a=0;

                   while(num--)

                   {

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

                            {

                                     getSin=sin(a); getCos=cos(a);

                                     down=left=MAX; up=right=MIN;

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

                                     {

                                               nx=x[j]*getCos-y[j]*getSin;

                                               ny=y[j]*getCos+x[j]*getSin;

                                               if(nx<left) left=nx;

                                               if(nx>right) right=nx;

                                               if(ny<down) down=ny;

                                               if(ny>up) up=ny;

                                     }

                                     border=right-left;

                                     border=(up-down)>border?(up-down):border;

                                     if(border<minBorder) minBorder=border,from=a;

                                     a+=stepLen;

                            }

                            a=from-stepLen;

                            stepLen/=4.5;

                   }

                   printf("%.2lf\n",minBorder*minBorder);

         }

         return 0;

}

【解题思路】

步步细化的时候也可用三分法,运气好的话0ms可过……

【AC的代码】

#include <iostream>

#include <cstdio>

#include <cmath>

#define MAX 1000000000

#define MIN -1000000000

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

using namespace std;

 

long x[31],y[31];

 

int main()

{

         long t,n,j,i;

         double stepLen,from,num,left,right,up,down;

         double nx,ny,border,minBorder,minA,a,getSin,getCos;

         scanf("%ld",&t);

         while(t--)

         {

                   scanf("%ld",&n);

                   for(j=0;j<n;j++) scanf("%ld%ld",&x[j],&y[j]);

                   from=0; num=40; minBorder=MAX; stepLen=PI/6; a=0;

                   while(num--)

                   {

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

                            {

                                     getSin=sin(a); getCos=cos(a);

                                     down=left=MAX; up=right=MIN;

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

                                     {

                                               nx=x[j]*getCos-y[j]*getSin;

                                               ny=y[j]*getCos+x[j]*getSin;

                                               if(nx<left) left=nx;

                                               if(nx>right) right=nx;

                                               if(ny<down) down=ny;

                                               if(ny>up) up=ny;

                                     }

                                     border=right-left;

                                     border=(up-down)>border?(up-down):border;

                                     if(border<minBorder) minBorder=border,from=a;

                                     a+=stepLen;

                            }

                            if(a) a=from-stepLen;

                            if(a==0||a==3) stepLen/=3;

                            else stepLen=stepLen*2/3;

                   }

                   printf("%.2lf\n",minBorder*minBorder);

         }

         return 0;

}

posted on 2010-03-05 10:26  liugoodness  阅读(347)  评论(0)    收藏  举报

导航