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;
}
时间: 2024-08-13 17:35:37

2015 百度之星 1006 矩形面积 最小点覆盖矩形的相关文章

HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015百度之星题目

B - 矩形面积 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input 第一行一个正整数 T,代表测试数据组数(),接下来 T 组测试数据. 每组测试数据占若干行,第一行一个正整数 ,代表矩形的数量.接下来 N 行,每行 8

二分搜索 2015百度之星初赛1 1003 序列变换

题目传送门 1 /* 2 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 3 比赛时以为是贪心,榨干智商也想不出来:( 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <iostream> 10 using

数学 2015百度之星初赛2 HDOJ 5255 魔法因子

题目传送门 1 /* 2 数学:不会写,学习一下这种解题方式:) 3 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) 4 (h*power+l+mid)*a = (l*power+h+mid)*b 5 可推得:mid = ((h*power+l) * a - (l*power+h) * b) / (a - b); 6 所以可以枚举h,l然后求mid,注意mid的最低位一定是0,因为留出最低位加l或者h 7

贪心/数学 2015百度之星资格赛 1004 放盘子

题目传送门 1 /* 2 贪心:小度熊先在多边形中间放一个盘子,接下来无论来访者怎么放,小度熊都根据多边形中心与来访者的盘子对称着放就能获胜. 3 题目已经给出方法,就是能否把盘子放在多边形中间,那么和边心距比较 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cmath> 8 #include <cstring> 9 using namespace std; 10 11 const i

找规律 2015百度之星资格赛 1001 大搬家

题目传送门 1 /* 2 找规律:题目真心读不懂,排列组合的题目 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 typedef long long ll; 11 12 const int MAXN = 1e6 + 10; 13 const int INF = 0x3f3

模拟 2015百度之星资格赛 1003 IP聚合

题目传送门 1 /* 2 模拟水题,排序后找出重复的ip就可以了 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <string> 9 #include <cmath> 10 using namespace std; 11 12 const int MAXN = 1e3 + 10;

LIS 2015百度之星初赛2 HDOJ 5256 序列变换

题目传送门 1 /* 2 LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载) 3 加入序列是1,2,2,2,3,这样求上升子序列是3,也就是要修改2个,但是中间的两个2,变化范围又不能超过(1,3) 4 那么这样求的也就不对,但是减掉之后,相当于给中间重复的数留下了修改的空间 5 解释下为什么可以减而保持正确性:因为题目所求时严格递增,假设是2,3, 4,那么变成1, 1, 1,所以在LIS里非严格递增就可以了 6 这也是为什么要在upp

字符串处理 2015百度之星资格赛 1002 列变位法解密

题目传送门 1 /* 2 字符串处理:要求解码,然而二维数组开不下,可以直接输出 3 只要在余数的地方判断一下就行了,vector的效率不高 4 另外:感觉麻烦的地方应该纸上写写就清楚了 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <string> 11 #include <cma

二分查找 2015百度之星初赛1 1001 超级赛亚ACMer

题目传送门 1 /* 2 二分找到不大于m的最大的数,记做p,只要a[p] + k <= a[p+1]就继续 3 注意:特判一下当没有比m小的数的情况:) 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 #include <algorithm> 9 using namespace std; 10 11 typedef long long ll; 12 13 const