zoukankan      html  css  js  c++  java
  • hdu3511-Prison Break

    纪念一下人生中第一道扫描线算法的题。。。。。其实不是严格上的第一道。。。第一次遇到的那个至今没过。。。。。

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=3511

    这题应该算是扫描线的基础题。

    对于每个圆,进入和出去的时候分别做扫描线,分别是x = c[i].x - c[i].r, x' = c[i].x + c[i].r;

    这样对于每条扫描线,对于x',我们在集合中删去这个圆,这很好理解。

    对于x,我们将这个圆加入集合,这样我们只要找向上第一个交的点和向下第一个交的点即可。

    不过问题来了,这个交点坐标随着扫描线的移动是在变化的,但我们注意到,这些点的相对位置并不变(即上面的还在上面,下面的还在下面)

    这样我们可以拉个set来维护扫描线上交点纵坐标,这个没必要存这个纵坐标的具体值,因为相对位置不变,树的结构也不变。

    只需要重载一下小于号在insert时候使用即可。

    如果扫描线向上或向下没有点,那么这个圆的depth = 1;

    如果上下两个点属于同一个圆id,那么这个圆的depth = depth[id]+1;

    如果上下两个圆属于不同的圆id1,id2,那么这个圆的depth = max(depth[id1], depth[id2]);

    AC代码:

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 const int maxn = 50000 + 10;
      5 
      6 typedef struct Circle{
      7   int id, x, y, r;
      8 
      9   Circle( int id = 0, int x = 0, int y = 0, int r = 0 ){
     10     this->id = id;
     11     this->x = x;
     12     this->y = y;
     13     this->r = r;
     14   }
     15 }Circle;
     16 
     17 Circle c[maxn];
     18 
     19 typedef struct Point{
     20   int id, ty;
     21 
     22   Point( int id = 0, int ty = 0 ){
     23     this->id = id;
     24     this->ty = ty;
     25   }
     26 }Point;
     27 
     28 set<Point> s;
     29 
     30 typedef struct Line{
     31   int id, x, ty;
     32 
     33   Line( int id = 0, int x = 0, int ty = 0 ){
     34     this->id = id;
     35     this->x = x;
     36     this->ty = ty;
     37   }
     38 
     39   bool operator < ( const Line& l )const{
     40     if( x == l.x )
     41       return id < l.id;
     42     return x < l.x;
     43   }
     44 }Line;
     45 
     46 Line l[maxn<<1];
     47 
     48 int depth[maxn];
     49 
     50 int n, ans, xlog;
     51 
     52 double intersector( const Point& p ){
     53   int id = p.id;
     54   double r = 1.0*c[id].r;
     55 
     56   double x = 1.0*(xlog - c[id].x);
     57   double y = sqrt((r*r - x*x));
     58 
     59   if(p.ty == 1)
     60     return 1.0*c[id].y + y;
     61   else
     62     return 1.0*c[id].y - y;
     63 }
     64 
     65 bool operator < ( const Point& p1, const Point& p2 ){
     66   if(p1.id == p2.id)
     67     return p1.ty < p2.ty;
     68   return intersector(p1) < intersector(p2);
     69 }
     70 
     71 void solve( int nn ){
     72   memset(depth, 0, sizeof(depth));
     73   s.clear();
     74   ans = 0;
     75 
     76   for( int i = 0; i < nn; ++i ){
     77     int id = l[i].id, ty = l[i].ty;
     78     xlog = l[i].x;
     79     //cout << "id: " << id << "   ty: " << ty << endl;
     80 
     81     if( ty == 1 ){
     82       s.erase(Point(id, 0));
     83       s.erase(Point(id, 1));
     84     }else{
     85       s.insert(Point(id, 0));
     86       set<Point>::iterator it1 = s.find(Point(id, 0)), it2;
     87       it2 = it1;
     88       it2++;
     89 
     90       if( it1 == s.begin() || it2 == s.end() ){
     91         depth[id] = 1;
     92         //cout << "id: " << id << "    depth[id]: " << depth[id] << endl;
     93       }else{
     94         it1--;
     95         if( it1->id == it2->id ){
     96           depth[id] = depth[it1->id]+1;
     97         }else{
     98           depth[id] = max( depth[it1->id], depth[it2->id] );
     99         }
    100         //cout << "id: " << id << "    depth[id]: " << depth[id] << endl;
    101       }
    102       s.insert(Point(id, 1));
    103     }
    104     ans = max( ans, depth[id]);
    105   }
    106 
    107   printf("%d
    ", ans);
    108 }
    109 
    110 int main(void){
    111   while(scanf("%d", &n) != EOF){
    112     memset( c, 0, sizeof(c) );
    113     memset( l, 0, sizeof(l) );
    114 
    115     for( int i = 0; i < n; ++i ){
    116       c[i].id = i;
    117       scanf("%d%d%d", &c[i].x, &c[i].y, &c[i].r);
    118       l[i*2] = Line(i, c[i].x-c[i].r, 0);
    119       l[i*2+1] = Line(i, c[i].x+c[i].r, 1);
    120     }
    121     int nn = n * 2;
    122     sort( l, l + nn );
    123 
    124     solve(nn);
    125   }
    126 
    127   return 0;
    128 }
    129 
    130 /*
    131 5
    132 0 0 100
    133 0 0 1
    134 0 5 3
    135 3 0 2
    136 0 0 200
    137 6
    138 0 0 100
    139 0 0 1
    140 0 5 3
    141 0 5 2
    142 3 0 2
    143 0 0 200
    144 */
    View Code
  • 相关阅读:
    文件操作
    内置函数
    lambda表达式
    函数基础
    基础数据类型-dict
    基础数据类型-tuple
    基础数据类型-list
    基础数据类型-set
    Python开发【第三篇】基本数据类型
    Python开发【第二篇】运算符
  • 原文地址:https://www.cnblogs.com/zhazhalovecoding/p/5403894.html
Copyright © 2011-2022 走看看