矩形面积

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 168    Accepted Submission(s): 93

Problem 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
 
Source

 #include<stdio.h>
#include<set>
#include<algorithm>
#include<string.h>
#define one first
#define two second
#define zero 1e-12
#define sgn(x) (fabs(x)<zero?0:(x>0?1:-1))
#define shadow(a,b,c) ((b.one-a.one)*(c.one-a.one)+(b.two-a.two)*(c.two-a.two))/sqrt((b.one-a.one)*(b.one-a.one)+(b.two-a.two)*(b.two-a.two))
#define cross(a,b,c) ((b.one-a.one)*(c.two-a.two)-(b.two-a.two)*(c.one-a.one))
#define cmp(a,b) (a.one<b.one || sgn(a.one-b.one)==0 && a.two<b.two)
const int M = , inf = 0x3f3f3f3f ;
int n ;
std::pair<double , double > p[M] ;
double s[M];
std::pair<double , double > jk[M] ;
int tot ; void hull(int l,int r, std::pair<double , double>a,std::pair<double , double> b){
int x=l,i=l-,j=r+,k;
for (k=l;k<=r;k++){
double temp=sgn(s[x]-s[k]);
if (temp< || temp== && cmp(p[x],p[k])) x=k;
}
std::pair<double , double> y=p[x];
for (k=l;k<=r;k++){
s[++i]=cross(p[k],a,y);
if (sgn(s[i])>) std::swap(p[i],p[k]); else i--;
}
for (k=r;k>=l;k--){
s[--j]=cross(p[k],y,b);
if (sgn(s[j])>) std::swap(p[j],p[k]); else j++;
}
if (l<=i) hull(l,i,a,y);
jk[tot ++] = y ;
if (j<=r) hull(j,r,y,b);
} void solve ()
{
double l , r , h , sum = inf ;
double d = ;
for (int i = ; i <= tot ; i ++) {
d = (jk[i].one - jk[i - ].one) * (jk[i].one - jk[i - ].one) + (jk[i].two - jk[i - ].two) * (jk[i].two - jk[i - ].two) ;
l = , r = sqrt (d) ;
h = ;
for (int j = ; j <= n ; j ++) {
if (p[j] != jk[i] && p[j] != jk[i - ]) {
h = std::max (h , fabs (cross (jk[i] , jk[i - ] , p[j])) / sqrt(d)) ;
l = std::min (l , shadow (jk[i] , jk[i - ] , p[j])) ;
r = std::max (r , shadow (jk[i] , jk[i - ] , p[j])) ;
}
}
sum = std::min (sum , (r - l) * h) ;
}
printf ("%.0f\n" , sum) ;
} int main(){
//freopen ("a.txt" , "r" , stdin) ;
int T , cas = ;
scanf ("%d" , &T) ;
while (T --) {
printf ("Case #%d:\n" , cas ++) ;
memset (s , , sizeof(s)) ;
int i , x= ;
tot = ;
scanf("%d",&n);
n *= ;
for (i=;i<=n;i++){
scanf("%lf%lf",&p[i].one,&p[i].two);
if (x== || cmp(p[i],p[x])) x=i;
}
std::swap(p[],p[x]);
jk[tot ++] = p[] ;
hull(,n,p[],p[]);
jk[tot] = jk[] ;
solve () ;
}
return ;
}

用这种做法,首先要明白最小的覆盖矩形的其中一边必定是和壳重合。

所以我们只要求出壳,并枚举壳上的每条边,并计算出在它上生成的最小矩阵面积。然后找出其中最小的就好了。

复杂度((4*n)^2);

 #include<bits/stdc++.h>
#define one first
#define two second
#define eps 1e-12
#define sgn(x) (x<eps?0:(x>0?1:-1))
#define cross(a,b,c) ((b.one-a.one)*(c.two-a.two)-(b.two-a.two)*(c.one-a.one))
#define cmp(a,b) (a.one<b.one || sgn(a.one-b.one)==0 && a.two<b.two)
const int M = 1e5 , inf = 0x3f3f3f3f ;
int n ;
std::pair<double , double> p [M] ;
int s[M] ;
std::pair<double , double> jk[M] ;
int tot = ; void hull (int l , int r , std::pair<double , double> a , std::pair<double , double> b)
{
//printf ("(%d , %d)\n" , l , r ) ;
int x = l , _l = l - , _r = r + ;
for (int i = l ; i <= r ; i ++) {
int tmp = sgn(s[i]-s[x]) ;
if (tmp > || tmp == && cmp(p[x],p[i])) x = i ;
}
for (int i = l ; i <= r ; i ++) {
s[++ _l] = cross(p[i],a,p[x]) ;
if (sgn(s[_l]) > ) std::swap (p[i] , p[_l]) ; else _l -- ;
}
for (int i = r ; i >= l ; i --) {
s[-- _r] = cross(p[i],p[x],b) ;
if (sgn(s[_r]) > ) std::swap (p[i] , p[_r]) ; else _r ++ ;
}
if (l <= _l)hull (l , _l , a , p[x]) ;
jk[tot ++] = p[x] ;
if (_r <= r)hull (_r , r , p[x] , b) ;
} int main ()
{
// freopen ("a.txt" , "r" , stdin ) ;
memset (s , , sizeof(s)) ;
scanf ("%d" , &n) ; //printf ("n = %d\n" , n ) ;
int x = - ;
for (int i = ; i <= n ; i ++) {
scanf ("%lf%lf" , &p[i].one , &p[i].two) ;
if (x == - || cmp (p[i] , p[x])) x = i ;
}
std::swap (p[x] , p[]) ;
jk[tot ++] = p[] ;
hull ( , n , p[] , p[]) ;
for (int i = ; i < tot ; i ++) printf ("(%.4f , %.4f)\n" , jk[i].one , jk[i].two) ;
return ;
}

92_quickhull

要了解这个算法的思路,先去维基上看看动态演示http://en.wikipedia.org/wiki/Quickhull

然后你需要知道叉积(叉积 "X" 表示):已知两个向量 a = (x1 , y1) , b = (x2 , y2);

叉积:a X b = x1 * y2 - x2 * y1 ;

点积:a * b = x1 * x2 + y1 * y2 ;

两个向量间的的夹角:a * b = |a| * |b| * cosθ ;

那么这两个向量 构成的三角形面积 S = 1/2 * abs (a X b) ,

还有 a X b = - b X a ;

知道以上这两个概念,就看的动quickhull了。

就这道题而言,你还需要知道,  a 在 b 上的投影求法a * b / | b | ;

2015baidu复赛 矩形面积(包凸 && ps:附quickhull模板)的更多相关文章

  1. 矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542

    今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个update,而且区间成段更新也没有lazy标记....研究了一下午,我突然我发现我以前根本不懂扫描线,之所以没有lazy标记, ...

  2. 2015年百度之星初赛(1) --- F 矩形面积

    矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少.   Input 第一行一个正整数 T, ...

  3. [LeetCode] Rectangle Area 矩形面积

    Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...

  4. POJ 1151 Atlantis(线段树-扫描线,矩形面积并)

    题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...

  5. 25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有

    package zhongqiuzuoye; //自己写的方法 public class Rect { public double width; public double height; Rect( ...

  6. 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

    Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit user ...

  7. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

  8. POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

    题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...

  9. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

随机推荐

  1. PHP设计模式(一)

    在码PHP程序的时候,为了以后更好地维护代码和理解代码,用一些合适的设计模式是必不可少的,下面我和大家首先分享下单例模式,有错误或者不恰当的地方,还望PHPer们帮我指出. 单例模式 PHP中的对象生 ...

  2. Android中运行的错误:java.lang.UnsatisfiedLinkError: Couldn't load locSDK3: findLibrary returned null.

    ---恢复内容开始--- 明明已经加入了liblocSDK3.so,但总是无法定位.提示错误java.lang.UnsatisfiedLinkError: Couldn't load locSDK3: ...

  3. WinForm------TextEdit控件去掉换行符

    //将换行转为空格 string str = this.DetailEdit.Text.Replace("\r\n"," ");

  4. matlab解三元二次方程组

    C1=7.0863; C2=6.8971; C3=0.4929; C4=0.8131; C5=1.8240; C6=3.8108; C7=3.7318; C8=-2.2238; C9=1.9905; ...

  5. spark 加载文件

    spark 加载文件 textFile的参数是一个path,这个path可以是: 1. 一个文件路径,这时候只装载指定的文件 2. 一个目录路径,这时候只装载指定目录下面的所有文件(不包括子目录下面的 ...

  6. re正则表达式7_{}

    curly brackets {} instead of one number, you can specify a range by writing a minimum,a comma,and a ...

  7. .Net中使用OracleDataAdapter

    本来只想简单记录一下OracleDataAdapter的批量增加和修改用法的,在园子里看到一篇比较详细的就在这分享了(Oracle Data Provider for .NET),虽然用的是 Upda ...

  8. Java——新IO 缓冲区与Buffer

    缓冲区和Buffer import java.nio.IntBuffer; //================================================= // File Na ...

  9. javascript 小技巧

    1:Boolean()==!! console.log(Boolean(888));//true console.log(!!(888));//true console.log(Boolean(&qu ...

  10. perspective属性

    1. 目前只有safari和chrome浏览器支持 -webkit-perspective. 2. 单位为像素 { -webkit-perspective:500 } 该属性只影响子元素的的透视效果.