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 }
没有人能阻止我前进的步伐,除了我自己!
原文地址:https://www.cnblogs.com/proverbs/p/2937922.html