Poj 3301:Texas Trip
After a day trip with his friend Dick, Harry noticed a strange pattern of tiny holes in the door of his SUV. The local American Tire store sells fiberglass patching material only in square sheets. What is the smallest patch that Harry needs to fix his door?
Assume that the holes are points on the integer lattice in the plane. Your job is to find the area of the smallest square that will cover all the holes.
Input
The first line of input contains a single integer T expressed in decimal with no leading zeroes, denoting the number of test cases to follow. The subsequent lines of input describe the test cases.
Each test case begins with a single line, containing a single integer n expressed in decimal with no leading zeroes, the number of points to follow; each of the following n lines contains two integers x and y, both expressed in decimal with no leading zeroes, giving the coordinates of one of your points.
You are guaranteed that T ≤ 30 and that no data set contains more than 30 points. All points in each data set will be no more than 500 units away from (0,0).
Output
Print, on a single line with two decimal places of precision, the area of the smallest square containing all of your points.
题意:平面坐标上有一些点(最多30个),求用最小面积的正方形,把它们覆盖完
题解:找到最远的两个点作为边长是不对的,因为正方形可以斜着放。正解是假设正方形的边与坐标轴平行,三分旋转的角度找到峰值。难点在于旋转坐标轴后点的新坐标。
可以说这道题开始完全没想到,直到刚看到题解时还有点懵O__O"…看懂之后才恍然大悟%>_<%,另外三分答案的做法也是第一次遇到(=^ ^=)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=30+10;
const double pi=acos(-1.0);
const double esp=1e-12;
const double inf=1e24;
struct node{
double x,y;
}point[N];
int T,n;
double getS(double a){
double len=-inf;
double Sin=sin(a),Cos=cos(a);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
double x=point[i].x-point[j].x;
double y=point[i].y-point[j].y;
double xx=fabs(x*Cos+y*Sin);
double yy=fabs(y*Cos-x*Sin);
len=max(len,max(xx,yy));
}
return len*len;
}
double devide(double l,double r){
if(r-l<=esp) return l;
double mid=(l+r)/2;
double s1=getS(mid);
double s2=getS((mid+r)/2);
return s1<s2?devide(l,(mid+r)/2):devide(mid,r);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
if(!n){printf("0.00\n");continue ;}
for(int i=1;i<=n;i++)
scanf("%lf %lf",&point[i].x,&point[i].y);
double a=devide(0,pi);
printf("%.2lf\n",getS(a));
}
}