poj3168离散化

扩地:有N块不重叠的矩形地,由左下角(A,B)和右上角(C,D)决定。如果两块地的边或角相交,则两块地都无法扩大。求多少地可以扩大?

思路:其实就是对x轴扫描,对y轴扫描。详见代码上的注释

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
	int p,mi,ma,id;
	node(){}
	node(int p,int mi,int ma,int id):p(p),mi(mi),ma(ma),id(id){}
	/*bool operator < (const node& rhs) const {
		return p < rhs.p || (p == rhs.p && mi < rhs.mi) ||
								(p == rhs.p && mi == rhs.mi && ma < rhs.ma);
							}*/
};
bool fg[25004];
vector<node> vx;
vector<node> vy;
bool cmp(node a,node b)
{
	if (a.p==b.p)
	{
		if(a.mi==b.mi)
			return a.ma<b.ma;
		else 
			return a.mi<b.mi;
	}
	else
		return a.p<b.p;
}
int main()
{
	//freopen("t.txt","r",stdin);
	int x1,x2,y1,y2,n,temp;
	while(scanf("%d",&n)!=EOF)
	{
		vx.clear();
		vy.clear();
		for(int i=0;i<n;i++)
		{
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			vx.push_back(node(y1,x1,x2,i));
			vx.push_back(node(y2,x1,x2,i));
			vy.push_back(node(x1,y1,y2,i));
			vy.push_back(node(x2,y1,y2,i));
		}
		sort(vx.begin(),vx.end(),cmp);
		sort(vy.begin(),vy.end(),cmp);
		memset(fg,true,sizeof(fg));
		temp=vx[0].ma;
		for(int i=1;i<vx.size();i++)
		{
			if(vx[i-1].p==vx[i].p){
				if(temp>=vx[i].mi)
					fg[vx[i].id]=fg[vx[i-1].id]=false;
					//这种方法类似于竹取法,显示讨论在同一行上的所有x,因为ximin 是从小到大排列的,所以每次搞得时候temp= max(temp,vx[i].ma),
					//这样下次的xi+1min>ximin,若是xi+1min仍然无法大于temp,说明一定被前面的区间包括了。 
				
			}else{
				temp=vx[i].ma;
			}
			temp=max(temp,vx[i].ma);
		}
		
		temp=vy[0].ma;
		for(int i=1;i<vy.size();i++)
		{
			if(vy[i-1].p==vy[i].p){
				if(temp>=vy[i].mi)
					fg[vy[i].id]=fg[vy[i-1].id]=false;
				
			}else{
				temp=vy[i].ma;
			}
			temp=max(temp,vy[i].ma);
		}
		int ans=0;
		for(int i=0;i<n;i++) 
			if(fg[i]) ans++;
		printf("%d\n",ans);
	} 
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/qq_39861441/article/details/83796211