矩形覆盖

Description

[题目描述]

在直角坐标系上,有N个边平行于坐标轴的矩形。求覆盖的面积

[数据范围]

1<=N<=100

每个坐标值为[-100000000,100000000]之间的整数。

[输入文件]

第一行一个整数N

后面有N行,每行4个整数: x1 y1 x2 y2, 分别表示先后各个矩形的左下角坐标和右上角坐标。

[输出文件]

一个整数。

输入样例

3

1 1 5 3

3 2 7 4

2 5 9 7

输出样例

28

题目分析:
看到这种题目的第一种想法无非是暴力枚举,当然那也是一种我们必须要掌握的方法,很好实现也有很低的思维复杂度,在考试中往往发挥奇效
这里先对暴力的方法进行简要说明,再说明优化后的方法
这种题目如果要写暴力的话,无非是暴力到了极致,通常一点的思路是对整个坐标的图进行枚举,统计重叠的面积
这种方法很容易想到,但是我们可能会被时间复杂度给劝退,需要去寻求一种更优的方法——离散化

假设我们有如图2个矩形:
在这里插入图片描述
其中蓝色的是重叠部分
纳闷我们根据离散化的原理进行映射后会变成这样(PS:其中蓝色的还是重叠部分):
在这里插入图片描述
根据对题中给出的左下角和右上角的坐标进行重组,我们可以得到如上图中黄色线交叉的点的坐标——我们于是可以得到途中由黄色线围成的小矩形——重叠的部分也包涵在其中!

问题解决了。
但是用总结性的话来说:这题枚举离散后形成的多个小矩形就可以了

代码:

#include<bits/stdc++.h>
using namespace std;

long long a1[201],a2[201],b1[202],b2[202],x[201],y[201];
long long n,ans=0;

int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
  		{
   			cin>>a1[i]>>b1[i]>>a2[i]>>b2[i];      //输入坐标
  			x[i]=a1[i],x[i+n]=a2[i],                      //存储坐标,用于离散化
    		y[i]=b1[i],y[i+n]=b2[i];
  	  	}
    //以排序的方式实现离散
    sort(x+1,x+n*2+1);
    sort(y+1,y+n*2+1);
    
    for (int i = 1; i <= 2*n-1; i++)            //到2n-1是因为我们需要将目前的和后面的一个配对成一个小矩形
        for (int j = 1; j <= 2*n-1; j++)
            for (int k = 1; k <= n; k++)            //枚举所有矩形
            	if (x[i] >= a1[k] && y[j] >= b1[k] && x[i+1] <= a2[k] && y[j+1] <= b2[k])         //判断是否是那两个的重叠部分
           	    	{
                  	  ans += (x[i+1]-x[i]) * (y[j+1]-y[j]);         //由于我们的坐标都不是在一侧的,所以可以直接这样来求出面积
                 
				  	  break;                 //直接跳出循环,避免有多个矩形重叠的情况——我们只计算一次
               		}
            
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值