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) 收藏 举报