Texas Trip

Description

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.

Sample Input

2
4
-1 -1
1 -1
1 1
-1 1
4
10 1
10 -1
-10 1
-10 -1
题意:给出平面上的n个点。求包围所有点的最小的正方形的面积。
解题思路:给定的所有的点。记录最左边最右边最上边的和最下边的位置。那么以上下和左右得到的最大长度为正方形的边肯定可以将所有的点都包围。
要想使正方形的面积最小。可以使旋转坐标系旋转一个角度。旋转角度在0-180之间。单峰。很明显可以采用三分的思想进行求解!
对于任意给定的两个点,(x1,x2),(y1,y2).过两点分别作两条平行线与x轴相交。夹角为d。那么两平行线的距离为:
s=fabs((x2-x1)*sind-(y2-y1)*cosd);s=fabs((x2-x1)*cosd+(y2-y1)*sind);
s会有两个值的原因是因为d可以为d也可为180-d。画图推导一下即可。
对任意一对点求距离的最大值。求出所有对定点在某旋转角度下的距离的最大。角度的三分便可以求出满足最小包围的最大边。此题需要注意精度!
AC代码:
#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
#define PI acos(-1.0)
int a[50];
int b[50];
int n;
double cal(double d)
{
    int i,j;
    double s1,s2,s=0.0;
    for(i=0;i<n-1;i++)
    {
        for(j=i+1;j<n;j++)
        {
            s1=fabs((a[j]-a[i])*sin(d)-(b[j]-b[i])*cos(d));
            s2=fabs((a[j]-a[i])*cos(d)+(b[j]-b[i])*sin(d));
            if(s1>s)  s=s1;
            if(s2>s)  s=s2;
        }
    }
    return s;
}
int main()
{
    int ca,i;
    double mid1,mid2,r,l;
    scanf("%d",&ca);
    while(ca--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
        }
        l=0.0;r=PI;
        while(r-l>1e-9)
        {
            mid1=(l+r)/2;
            mid2=(mid1+r)/2;
            if(cal(mid1)>cal(mid2))  l=mid1;
            else r=mid2;
        }
        double temp=cal(mid1);
        printf("%.2lf\n",temp*temp);
    }
    return 0;
}


posted @ 2013-05-20 20:07  forevermemory  阅读(372)  评论(0编辑  收藏  举报