HDU 3511 扫描线算法

今天在知道STL::set居然是可以在线调整的,瞬间给跪了啊。。。这TM都是怎么样的设计思想。。。

 

//Result:2012-07-27 15:09:17	Accepted	3511	687MS	8964K	2667 B	G++	
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>

using namespace std;

#define print(x) cout<<x<<endl
#define input(x) cin>>x
#define SIZE 50010

const double eps=1e-8;
double xx;

inline double mul(double x)
{
	return x*x;
}

inline int zero(double x)
{
	if(x>eps) return 1;
	else if(x<-eps) return -1;
	else return 0;
}

struct point 
{
	double x,y;
	point(){}
	point(double ix,double iy)
	{
		x=ix;y=iy;
	}
};

struct circle
{
	point p;
	double r;
	circle(){}
	circle(point ip,double ir)
	{
		p=ip;r=ir;
	}
};

circle array[SIZE];

struct mark
{
	point p;
	int id;
	bool io;

	mark(){}
	mark(point ip,int iid,bool iio)
	{
		p=ip;id=iid;io=iio;
	}
	
	mark getFriend()
	{
		mark res=(*this);
		res.io=!res.io;
		return res;
	}

	double y_axis() const
	{
		double a=sqrt(mul(array[id].r)-mul(xx-array[id].p.x));
		
		if(io) return p.y-a;
		else return p.y+a;
	}

	bool operator < (const mark &b) const
	{
		double y1=y_axis();
		double y2=b.y_axis();
		//print(y1<<' '<<y2);
		if(zero(y1-y2)) return y1<y2;
		else if(id!=b.id) return id<b.id;
		return io>b.io;
	}
};

mark markio[SIZE<<1];
int cnt,n;
int dp[SIZE];


bool cmp(const mark& a,const mark& b)
{
	return a.p.x<b.p.x;
}

void slove()
{
	set<mark> st;
	set<mark>::iterator now,next,pre;
	memset(dp,0,sizeof(dp));
	for(int i=0;i<cnt;i++)
	{
		if(!markio[i].io)
		{
			mark tmp=markio[i];
			st.erase(tmp);
			tmp=tmp.getFriend();
			st.erase(tmp);
		}
		else
		{
			xx=markio[i].p.x;
			mark tmp=markio[i];
			st.insert(tmp);
			
			/*
			for(set<mark>::iterator iter=st.begin();iter!=st.end();iter++)
			{
				printf("%.2lf %.2lf -> %d  -> %2.lf\n",iter->p.x,iter->p.y,iter->id,iter->y_axis());
			}
			puts("");
			*/
			
			next=pre=now=st.find(tmp);
			next++;
			if(pre==st.begin() or next==st.end()) dp[tmp.id]=1;
			else
			{
				pre--;
				int id1=pre->id,id2=next->id;
				if(id1==id2) dp[tmp.id]=dp[id1]+1;
				else dp[tmp.id]=max(dp[id1],dp[id2]);
			}
			tmp=tmp.getFriend();
			st.insert(tmp);
		}
	}
}

int main()
{
	double a,b,c;
	while(input(n))
	{
		cnt=0;
		memset(markio,0,sizeof(markio));
		for(int i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&a,&b,&c);
			array[i]=circle(point(a,b),c);
			markio[cnt++]=mark(point(a-c,b),i,1);
			markio[cnt++]=mark(point(a+c,b),i,0);
		}
		sort(markio,markio+cnt,cmp);
		slove();
		int ans=0;
		for(int i=0;i<n;i++)
		{
			ans=max(dp[i],ans);
		}
		print(ans);
	}
	return 0;
}

  

posted on 2012-07-27 15:15  Wizmann  阅读(291)  评论(0编辑  收藏  举报

导航