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;

}

  

你可能感兴趣的:(HDU)