题意:
给出n个工厂和m个城市的位置,此地区常年吹西北风,所以城市不能在工厂的东南方向,问m个城市的位置中哪些位置建城市不会被工厂污染,先输出可选择城市的位置,在输出这些城市的坐标,按横坐标由小到大输出,横坐标相同按纵坐标由小到大输出。
思路:也就是说如果有一个工厂在一个打算建城市的左上角,那么该地点就不能建城市(因为会污染)。
如果有一个工厂x坐标<=城市的坐标,工厂的y坐标>=城市的y坐标,那么该地点不可行。(其实就是看城市点的左上角是否有工厂)。
如果我们想要知道点i(xi,yi)是否可以建城市,我们需要怎么做?
只需要看二维坐标轴,点i的左边是否有一个工厂点的y坐标>=yi即可。
如何快速的确定所有的城市点是否可行?
我们通过将所有工厂和城市点按x从小到大,(如果x相等,则y从大到小,如果x和y都相等,就把工厂排在城市前面)的顺序排序.
现在我们确定了x坐标一定是从小到大排序的,所以如果我们当前考虑第i个点(该点是城市)是否可行时?我们只要从0到i-1这些点中找出是否有一个工厂的y坐标大于等于它的y坐标就行(因为这前面任意工厂的x坐标肯定<=该地点的x坐标).
所以程序中我们用y来记录我们当前所遇到过的所有工厂中y坐标的最大值.如果这个最大值依然小于当前城市点的y坐标,那么就不可能有妨碍该城市的工厂存在了.(因为只有城市点左边的工厂才可能妨碍该点建立城市)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=400010;
struct node
{
int x,y;
bool f;
};
bool cmp(node a,node b)
{
if(a.x!=b.x)
return a.x<b.x;
if(a.y!=b.y)
return a.y>b.y;
return a.f>b.f;
}
node no[maxn];
struct nod
{
int x,y;
};
bool cm(node a,node b)
{
if(a.x!=b.x)
return a.x<b.x;
if(a.y!=b.y)
a.y<b.y;
}
node N[maxn];
int main()
{
int n,m,i,cnt,maxy;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n+m;i++)
{
scanf("%d%d",&no[i].x,&no[i].y);
if(i<=n)
no[i].f=0;
else
no[i].f=1;
}
sort(no+1,no+1+n+m,cmp);
//for(i=1;i<=n+m;i++)
//cout<<no[i].x<<" "<<no[i].y<<" "<<no[i].f<<endl;
maxy=-2000000000;
cnt=0;
for(i=1;i<=n+m;i++)
{
if(no[i].f)
{
if(maxy<no[i].y)
maxy=no[i].y;
}
else
{
if(maxy>=no[i].y)
continue;
else
{
cnt++;
N[cnt].x=no[i].x;
N[cnt].y=no[i].y;
}
}
}
sort(N+1,N+1+cnt,cm);
printf("%d\n",cnt);
for(i=1;i<=cnt;i++)
printf("%d %d\n",N[i].x,N[i].y);
//printf("%d %d\n",N[cnt].x,N[cnt].y);
}
}