zoj 3041 City Selection

呃。。群上一个朋友问我呢,说是离散化。。我正好想练练(今天下午暴力过了个离散化的= = 。。表示对离散化很有好感。。)

这题是给了N个可选城市的坐标和M个工厂的坐标。如果一个城市的左上方(西北)有工厂,这个地点就被污染了(也就是工厂的右下方向,东南象限)。这个地方就不能建城市了。让你输出可以建城市的地点。

想了想,没啥必要离散化啊,直接按 Y 坐标从大往小排序,求出在城市 K 之前 最小的 X坐标。如果这个坐标比K的X坐标小或者相等,则这个城市就被污染了。因为是Y从大往小排,所以不用考虑Y坐标了。

然后就按人家要求输出就好了。跑了1秒多。。。也归到计算几何好了。。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <climits>

using namespace std;

const int MAX = 400010;
struct point {int x,y;bool f;};
point p[MAX];
point out[MAX/2];
bool cmp(point a,point b)
{
	if( a.x == b.x && a.y == b.y )
		return !a.f;
	if( a.y == b.y )
		return a.x < b.x;
	return a.y > b.y;
}
bool cmpout(point a,point b)
{
	if( a.x == b.x )
		return a.y < b.y;
	return a.x < b.x;
}
int main()
{
	int n,m,x;
	
	while( ~scanf("%d%d",&n,&m) )
	{
		int cnt = 0;
		for(int i=0; i<n; i++)
		{
			scanf("%d%d",&p[i].x,&p[i].y);
			p[i].f = true;
		}
		for(int i=n; i<n+m; i++)
		{
			scanf("%d%d",&p[i].x,&p[i].y);
			p[i].f = false;
		}
		sort(p,p+n+m,cmp);
		int x = INT_MAX;
		for(int i=0; i<n+m; i++)
		{
			if( p[i].f == true )
			{
				if( !( x <= p[i].x ) )
					out[cnt++] = p[i];
			}
			else
			{
				if( p[i].x < x )
					x = p[i].x;
			}
		}
		sort(out,out+cnt,cmpout);
		printf("%d\n",cnt);
		for(int i=0; i<cnt; i++)
			printf("%d %d\n",out[i].x,out[i].y);
	}	
return 0;
}


你可能感兴趣的:(zoj 3041 City Selection)