poj2932(计算几何平面扫描)

解题思路:其实就是把圆的左右两端记录下来,然后沿x轴从左到右进行扫描,扫到圆的左端点时,则判断其是否被其他圆包含,如果不被包含就加入set中维护,到碰到圆的右端点时,就从set中删除左端点。但做的时候调了一些时间,发现有个以前没注意到的语法问题。网上的版本都是用pair进行数据组合的,这样排序的时候就会默认先以first进行排,first一样时就按second的大小排序。而我用结构体,只按first进行排序会出错。但为什么在x一样的情况下还要用id来进行排序呢?主要还是因为用了lower_bound这个函数,不把id也排序,则在x相同时id是出于无序状态的。

#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
double ax[40009],ay[40009],ar[40009];
struct node
{
	int id;
	double x;
	node(){
	}
	node(double x,int id):x(x),id(id){
	}
};
struct node2
{
	int id;
	double y;
	node2(){}
	node2(double y,int id):id(id),y(y){
	}
};
bool operator<(const node2 &a,const node2 &b)
{
	if(a.y==b.y)
	return a.id<b.id;
	return a.y<b.y;
}
bool cmp(node &a,node &b)
{
	if(a.x==b.x)
	return a.id<b.id;
	return a.x<b.x;
}
set<node2> s;
vector<node> t;
vector<int> p;
bool judge(int id1,int id2)//判断y1 
{
	double dx=ax[id1]-ax[id2],dy=ay[id1]-ay[id2];
	return dx*dx+dy*dy<=ar[id2]*ar[id2];
}
int main()
{
	//freopen("t.txt","r",stdin);
	int n;
	double r,x,y;
	node tp;
	set<node2>::iterator it;
	scanf("%d",&n);
	//while(scanf("%d",&n)!=EOF)
	{
		p.clear();
		s.clear();
		t.clear();
		for(int i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&r,&x,&y);
			t.push_back(node(x-r,i));
			t.push_back(node(x+r,i+n));
			ax[i]=x;ay[i]=y;ar[i]=r;
		}
		sort(t.begin(),t.end(),cmp);
		/*for(int i=0;i<t.size();i++)
		printf("%lf ",t[i].x);*/
		for(int i=0;i<t.size();i++)
		{
			tp=t[i];
			if(tp.id>=n)
			{
				s.erase(node2(ay[tp.id-n],tp.id-n));
			}else
			{
				it=s.lower_bound(node2(ay[tp.id],tp.id));
				if(it!=s.end()&&judge(tp.id,it->id)) continue;
				if(it!=s.begin()&&judge(tp.id,(--it)->id)) continue;
				p.push_back(tp.id);
				s.insert(node2(ay[tp.id],tp.id));			
			}
		}
		sort(p.begin(),p.end());
		printf("%d\n",p.size());
		for(int i=0;i<p.size();i++)
		printf("%d%c",p[i]+1,i+1==p.size()?'\n':' ');
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39861441/article/details/87787728
今日推荐