2015 百度之星 1006 矩形面积 最小点覆盖矩形

矩形面积

Time Limit: 20 Sec  Memory Limit: 256 MB

题目连接

http://acdream.info/problem?pid=1754

Description

小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。

Input

第一行一个正整数 T,代表测试数据组数(1≤T≤20),接下来 T 组测试数据。

每组测试数据占若干行,第一行一个正整数 N(1≤N<≤1000),代表矩形的数量。接下来 N 行,每行 8 个整数x1,y1,x2,y2,x3,y3,x4,y4,代表矩形的四个点坐标,坐标绝对值不会超过10000。

 

Output

对于每组测试数据,输出两行:

第一行输出"Case #i:",i 代表第 i 组测试数据。 第二行包含1 个数字,代表面积最小的矩形的面积,结果保留到整数位。

 

Sample Input

 

2 2 5 10 5 8 3 10 3 8 8 8 8 6 7 8 7 6 1 0 0 2 2 2 0 0 2

 

Sample Output

Case #1:
17
Case #2:
4


 

HINT

题意

 

题解:

套版,套版

代码:

 

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)  
#define maxn 2000001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void P(int x)
{
    Num=0;if(!x){putchar('0');puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************

struct Point
{
    double x,y;
    Point(){}
    Point(double x0,double y0):x(x0),y(y0){}
};

const int INF = 999999999;

Point p[maxn];
int con[maxn];
int cn;
int n;

struct Line
{
    Point a,b;
    Line(){}
    Line(Point a0,Point b0):a(a0),b(b0){}
};

double xm(Point o,Point a,Point b)
{
    return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}
double dm(Point o,Point a,Point b)
{
    return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y);
}

int sgn(double a)
{
    return a<-eps?-1:a>eps;
}

double dist(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

int cmp(Point a,Point b)
{
    double d=xm(p[0],a,b);
    if(d>0)
        return 1;
    if(d==0 && dist(p[0],a)<dist(p[0],b))
        return 1;
    return 0;
}

void Graham()
{
    int i,ind=0;
    for(i=1;i<n;i++)
    if(p[ind].y>p[i].y || (p[ind].y==p[i].y) && p[ind].x>p[i].x)
         ind=i;
    swap(p[ind],p[0]);
    sort(p+1,p+n,cmp);
    con[0]=0;
    con[1]=1;
    cn=1;
    for(i=2;i<n;i++)
    {
         while(cn>0 && sgn(xm(p[con[cn-1]],p[con[cn]],p[i]))<=0)
         cn--;
         con[++cn]=i;
    }
    int tmp=cn;
    for(i=n-2;i>=0;i--)
    {
         while(cn>tmp && sgn(xm(p[con[cn-1]],p[con[cn]],p[i]))<=0)
         cn--;
         con[++cn]=i;
    }
}

double Solve()
{
    int t,r,l;
    double ans=INF;
    t=r=1;
    if(cn<3)
        return 0;
    for(int i=0;i<cn;i++)
    {
        while(sgn(xm(p[con[i]],p[con[i+1]],p[con[t+1]])-xm(p[con[i]],p[con[i+1]],p[con[t]]))>0)
          t=(t+1)%cn;
        while(sgn(dm(p[con[i]],p[con[i+1]],p[con[r+1]])-dm(p[con[i]],p[con[i+1]],p[con[r]]))>0)
          r=(r+1)%cn;
        if(!i) l=r;
        while(sgn(dm(p[con[i]],p[con[i+1]],p[con[l+1]])-dm(p[con[i]],p[con[i+1]],p[con[l]]))<=0)
          l=(l+1)%cn;
        double d=dist(p[con[i]],p[con[i+1]]);
        double tmp=xm(p[con[i]],p[con[i+1]],p[con[t]])*(dm(p[con[i]],p[con[i+1]],p[con[r]])-dm(p[con[i]],p[con[i+1]],p[con[l]]))/d/d;
        ans=min(ans,tmp);
    }
    return ans;
}

int main()
{
    int i;
    int T, cas = 0;
    scanf("%d", &T);
    while(T--)
    {
      scanf("%d", &n);
      n *= 4;
      for(i=0;i<n;i++)
          scanf("%lf%lf",&p[i].x,&p[i].y);
      Graham();
      printf("Case #%d:\n%.0f\n",++cas, Solve());
    }
    return 0;
}

 

你可能感兴趣的:(百度)