离散化的应用:矩形覆盖问题

给出一列矩形,求被矩形覆盖的面积总共有多少?

显然,最简单的办法就是模拟.设置一个布尔型二维数组,将有矩形覆盖的方格填上1,最后统计一遍即可.

但是复杂度相当可惜,和坐标系面积和举行个数以及矩形平均面积成正比.也就是说,如果坐标系范围在[-10000000,10000000]之间,就肯定过不了了.不仅过不了,而且存不下.10000x10000都困难.

有什么办法可以解决呢?注意n的值不大,所以有很多坐标数字都是不必须的,那么让我们"压缩"坐标系,将所有出现过的坐标都记录到一个hash数组中,那么就可以达到离散化的作用了.

附:color代码

#include 
#include 
struct rect{
	int x1,x2,y1,y2,size,id;
} rects[100];
inline bool cmp(rect a,rect b){
	return (a.size>b.size?true:(a.size==b.size?(a.id<b.id):false));
}
inline bool cmp2(rect a,rect b){
	return a.id<b.id;
}
int n,a,i,j,xx,yy;
int xs[30000],ys[30000],xp[30000],yp[30000],xa,ya;
int map[400][400];
bool pss[400];
int main(){
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
	scanf("%d %d",&n,&a);
	for(i=0;i<n;++i){
		scanf("%d %d %d %d",&rects[i].x1,&rects[i].y1,&rects[i].x2,&rects[i].y2);
		rects[i].id=i;
		(rects+i)->x1+=15000;
		(rects+i)->x2+=15000;
		(rects+i)->y1+=15000;
		(rects+i)->y2+=15000;
		xs[(rects+i)->x1]=1;
		xs[(rects+i)->x2]=1;
		ys[(rects+i)->y1]=1;
		ys[(rects+i)->y2]=1;
	}
	xs[0]=ys[0]=1;
	xs[30000]=ys[30000]=1;
	j=0;
	for(i=0;i<=30000;++i) if(xs[i]) xp[(xs[i]=j++)]=i;
	xa=j;
	j=0;
	for(i=0;i<=30000;++i) if(ys[i]) yp[(ys[i]=j++)]=i;
	ya=j;
	for(i=0;i<n;++i){
		(rects+i)->x1=xs[(rects+i)->x1];
		(rects+i)->x2=xs[(rects+i)->x2];
		(rects+i)->y1=ys[(rects+i)->y1];
		(rects+i)->y2=ys[(rects+i)->y2];
		for(xx=rects[i].x1;xx<rects[i].x2;++xx){
			for(yy=rects[i].y1;yy<rects[i].y2;++yy){
				map[xx][yy]=i+1;
			}
		}
	}
	for(xx=0;xx<xa;++xx){
		for(yy=0;yy<ya;++yy){
			if(map[xx][yy]){
				rects[map[xx][yy]-1].size+=(xp[xx+1]-xp[xx])*(yp[yy+1]-yp[yy]);
			}
		}
	}
	std::sort(rects,rects+n,cmp);
	for(i=0;i<a;++i){
		pss[rects[i].id]=true;
	}
	for(i=0;i<n;++i){
		if(pss[i]) printf("%d ",i);
	}
	return 0;
}

  

 

转载于:https://www.cnblogs.com/tmzbot/p/3985814.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值