【计算几何】面积 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://blog.csdn.net/jiangzh7
*/
#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;
}

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值