HDU 3511 圆的扫描线
题意:
给了n(n<50000)圆的圆心坐标和半径,任意两个圆不会相切或者相交,也就是说只存在内含和相离两种关系,问最深的那个圆被嵌套了多少次。
题解:
抄的别人的。。然后自己还不会nlogn的实现。。
后来看别人代码,发现,set用的太神了!
比较函数中有一个变量,但是这个变量的改变并不会影响set的形态!所以不会出问题!
http://hi.baidu.com/bobo__bai/item/17f7b28bd5994a5d850fab39
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 #include <set> 7 #include <cmath> 8 9 #define N 222222 10 11 using namespace std; 12 13 struct C 14 { 15 int x,y,r,w; 16 }c[N]; 17 18 struct E 19 { 20 int x,id,fg; 21 }li[N]; 22 23 int n,nx,cnt; 24 25 inline double gety(int id,int fg) 26 { 27 double dy=sqrt(c[id].r*1.0*c[id].r-(nx-c[id].x)*1.0*(nx-c[id].x));//爆int!! 28 if(fg==1) return dy+c[id].y; 29 return -dy+c[id].y; 30 } 31 32 struct SL 33 { 34 int fg,id; 35 bool operator<(const SL a) const 36 { 37 double y1=gety(id,fg); 38 double y2=gety(a.id,a.fg); 39 if(y1==y2) return fg>a.fg; 40 else return y1>y2; 41 } 42 }; 43 44 set<SL> s; 45 set<SL>::iterator pre,suc,it; 46 47 inline void add(C &c,int id) 48 { 49 li[++cnt].id=id; li[cnt].x=c.x-c.r; li[cnt].fg=1; 50 li[++cnt].id=id; li[cnt].x=c.x+c.r; li[cnt].fg=-1; 51 } 52 53 inline bool cmp(const E &a,const E &b) 54 { 55 if(a.x==b.x) return c[a.id].y>c[b.id].y; 56 return a.x<b.x; 57 } 58 59 inline void read() 60 { 61 cnt=0; 62 for(int i=1;i<=n;i++) 63 { 64 scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r); 65 c[i].w=0; 66 add(c[i],i); 67 } 68 sort(li+1,li+1+cnt,cmp); 69 } 70 71 inline void go() 72 { 73 s.clear(); 74 SL node; 75 for(int i=1;i<=cnt;i++) 76 { 77 nx=li[i].x; 78 if(li[i].fg==1) 79 { 80 node.id=li[i].id; node.fg=1; 81 it=s.insert(node).first;//.first返回插入位置,.second返回是否插入成功 82 suc=pre=it; suc++; 83 if(it==s.begin()||suc==s.end()) c[it->id].w=1; 84 else 85 { 86 pre--; 87 if(pre->id==suc->id) c[it->id].w=c[pre->id].w+1; 88 else c[it->id].w=max(c[pre->id].w,c[suc->id].w); 89 } 90 node.fg=-1; s.insert(node); 91 } 92 else 93 { 94 node.id=li[i].id; node.fg=1; s.erase(node); 95 node.fg=-1; s.erase(node); 96 } 97 } 98 int ans=0; 99 for(int i=1;i<=n;i++) ans=max(ans,c[i].w); 100 printf("%d\n",ans); 101 } 102 103 int main() 104 { 105 while(scanf("%d",&n)!=EOF) read(),go(); 106 return 0; 107 }
没有人能阻止我前进的步伐,除了我自己!