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;
}
浙公网安备 33010602011771号