【计算几何】面积 area.pas/c/cpp
面积
area.pas/c/cpp
问题描述:
给你一个长L,宽W的矩形纸,上面有n个黑点,你需要在这张纸上找出一个平行于坐标轴的最大矩形,使这个矩形中不包含黑点(可以在矩形边框上)。纸的一个顶点在(0,0),另一个顶点在(L,W)。
输入:
输入文件的第一行包含两个整数L和W,分别表示纸的长和宽。文件的第二行包含一个整数n,表示黑点的数量。以下n行每行包含两个整数x和y,表示一个黑点的坐标,可能重复。所有黑点都位于矩形纸内,即:0<=x<=L,0<=y<=W。
输出:
输出文件仅一行,包含一个整数S,表示找到的矩形最大面积。
输入样例:
10 10
4
1 1
9 1
1 9
9 9
输出样例:
80
数据范围:
1<=L,W<=10000
对于50%的数据0<=n<=50
对于80%的数据0<=n<=200
对于100%的数据0<=n<=1000
这一题由于矩形面积大,点较少,所以O(L*M)的悬线法就没法AC,只有80分
这里就要用到最大子矩形的O(n2)的算法,至于算法的实现,看看代码,分别按 x 和 y 排序,找两次
C++ Code
/* C++ Code http://oijzh.cnblogs.com */ #include<cstdio> #include<algorithm> using namespace std; #define MAXN 1010 #define max(a,b) (a)>(b)?(a):(b) struct node{int x,y;}; int L,W,n; node a[MAXN]; bool cmp1(node a,node b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } bool cmp2(node a,node b) { if(a.y==b.y)return a.x<b.x; return a.y<b.y; } int main() { freopen("area.in","r",stdin); freopen("area.out","w",stdout); scanf("%d%d",&L,&W);//长 L 宽 W scanf("%d",&n); int i,j; for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); a[++n].x=0;a[n].y=W; a[++n].x=L;a[n].y=0; sort(a+1,a+1+n,cmp1); int best=0; int high,low,maxx; for(i=1;i<n;i++) { high=W,low=0; for(j=i+1;j<=n;j++) if(a[i].y>=low&&a[i].y<=high) { if(a[i].y==a[j].y)break; best=max(best,(a[j].x-a[i].x)*(high-low)); if(a[j].y>a[i].y&&a[j].y<=high) high=a[j].y; if(a[j].y<a[i].y&&a[j].y>=low) low=a[j].y; } } sort(a+1,a+1+n,cmp2); for(i=1;i<n;i++) { high=W,low=0; for(j=i+1;j<=n;j++) if(a[i].x>=low&&a[i].x<=high) { if(a[i].x==a[j].x)break; best=max(best,(a[j].y-a[i].y)*(high-low)); if(a[j].x>a[i].x&&a[j].x<=high) high=a[j].x; if(a[j].x<a[i].x&&a[j].x>=low) low=a[j].x; } } printf("%d",best); return 0; }
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh