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

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

显然,最简单的办法就是模拟.设置一个布尔型二维数组,将有矩形覆盖的方格填上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;
}

  

时间: 2024-10-14 16:05:10

离散化的应用:矩形覆盖问题的相关文章

BZOJ1185: [HNOI2007]最小矩形覆盖

传送门 旋转卡壳. 首先求凸包没什么好商量的. 然后有一个结论,如果存在一个最小的矩形覆盖,那么凸包里必定存在一条边和矩形的边重合. 自己yy一下就好啦,很容易想明白. 然后枚举每条边,移动另外三条边即可. 注意点积,叉积的结合运用什么的. //BZOJ 1185 //by Cydiater //2017.1.29 #include <iostream> #include <map> #include <ctime> #include <cmath> #in

NOIP2002 矩形覆盖

题四 矩形覆盖(存盘名NOIPG4) [问题描述]: 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴.当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4.问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢.约定:

NOIP2002矩形覆盖[几何DFS]

题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴.当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4.问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢.约定:覆盖一个点的矩形面积为 0:覆盖平行于坐标轴

HDU 5100 Chessboard 用 k &#215; 1 的矩形覆盖 n &#215; n 的正方形棋盘

点击打开链接 Chessboard Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 335    Accepted Submission(s): 168 Problem Description Consider the problem of tiling an n×n chessboard by polyomino pieces tha

1185: [HNOI2007]最小矩形覆盖

1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1426  Solved: 648[Submit][Status][Discuss] Description Input Output Sample Input Sample Output HINT Source 计算几何 vfleaking提供Spj #include<cstdio> #include<cmat

剑指OFFER之矩形覆盖(九度OJ1390)

题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入包括一个整数n(1<=n<=70),其中n为偶数. 输出: 对应每个测试案例, 输出用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有的方法数. 样例输入: 4 样例输出: 5 解题思路: 观察题目中的矩形,2*n的,是个长条形.本来脑中想象的是复杂的华容道,但是既然只是简单的长条形,那么

bzoj1185【HNOI2007】最小矩形覆盖

1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1114  Solved: 505 [Submit][Status][Discuss] Description 凸包+旋转卡壳 首先有一个结论:矩形一定有一条边在凸包上,否则我们旋转之后一定会得到一个更小的矩形,脑补一下. 然后枚举凸包上的边,用旋转卡壳维护矩形的另外三条边,同时更新答案即可. #include<ios

[ACM] ZOJ 3209 Treasure Map ( Dancing Links 精确覆盖,矩形覆盖)

Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of a treasure map. Unfortunately, all the copies are now broken to many rectangular pieces, and what make it worse, he has lost some of the pieces. Luck

洛谷 P1034 矩形覆盖

P1034 矩形覆盖 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴.当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4.问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢.约定:覆盖一个点的矩形面积为