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

题目链接:

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代码:

 #include <bits/stdc++.h>

 using namespace std;
const int maxn = + ; typedef struct Circle{
int id, x, y, r; Circle( int id = , int x = , int y = , int r = ){
this->id = id;
this->x = x;
this->y = y;
this->r = r;
}
}Circle; Circle c[maxn]; typedef struct Point{
int id, ty; Point( int id = , int ty = ){
this->id = id;
this->ty = ty;
}
}Point; set<Point> s; typedef struct Line{
int id, x, ty; Line( int id = , int x = , int ty = ){
this->id = id;
this->x = x;
this->ty = ty;
} bool operator < ( const Line& l )const{
if( x == l.x )
return id < l.id;
return x < l.x;
}
}Line; Line l[maxn<<]; int depth[maxn]; int n, ans, xlog; double intersector( const Point& p ){
int id = p.id;
double r = 1.0*c[id].r; double x = 1.0*(xlog - c[id].x);
double y = sqrt((r*r - x*x)); if(p.ty == )
return 1.0*c[id].y + y;
else
return 1.0*c[id].y - y;
} bool operator < ( const Point& p1, const Point& p2 ){
if(p1.id == p2.id)
return p1.ty < p2.ty;
return intersector(p1) < intersector(p2);
} void solve( int nn ){
memset(depth, , sizeof(depth));
s.clear();
ans = ; for( int i = ; i < nn; ++i ){
int id = l[i].id, ty = l[i].ty;
xlog = l[i].x;
//cout << "id: " << id << " ty: " << ty << endl; if( ty == ){
s.erase(Point(id, ));
s.erase(Point(id, ));
}else{
s.insert(Point(id, ));
set<Point>::iterator it1 = s.find(Point(id, )), it2;
it2 = it1;
it2++; if( it1 == s.begin() || it2 == s.end() ){
depth[id] = ;
//cout << "id: " << id << " depth[id]: " << depth[id] << endl;
}else{
it1--;
if( it1->id == it2->id ){
depth[id] = depth[it1->id]+;
}else{
depth[id] = max( depth[it1->id], depth[it2->id] );
}
//cout << "id: " << id << " depth[id]: " << depth[id] << endl;
}
s.insert(Point(id, ));
}
ans = max( ans, depth[id]);
} printf("%d\n", ans);
} int main(void){
while(scanf("%d", &n) != EOF){
memset( c, , sizeof(c) );
memset( l, , sizeof(l) ); for( int i = ; i < n; ++i ){
c[i].id = i;
scanf("%d%d%d", &c[i].x, &c[i].y, &c[i].r);
l[i*] = Line(i, c[i].x-c[i].r, );
l[i*+] = Line(i, c[i].x+c[i].r, );
}
int nn = n * ;
sort( l, l + nn ); solve(nn);
} return ;
} /*
5
0 0 100
0 0 1
0 5 3
3 0 2
0 0 200
6
0 0 100
0 0 1
0 5 3
0 5 2
3 0 2
0 0 200
*/

hdu3511-Prison Break的更多相关文章

  1. hdu3511 Prison Break 圆的扫描线

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3511 题目: Prison Break Time Limit: 10000/5000 MS ( ...

  2. HDU 3681 Prison Break(BFS+二分+状态压缩DP)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  3. hdu 3681 Prison Break (TSP问题)

    Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  4. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  5. Prison Break

    Prison Break 时间限制: 1 Sec  内存限制: 128 MB提交: 105  解决: 16[提交][状态][讨论版] 题目描述 Scofild又要策划一次越狱行动,和上次一样,他已经掌 ...

  6. HDU3681 Prison Break

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  7. 1254 - Prison Break

    1254 - Prison Break   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Mic ...

  8. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  9. hdu 3681 Prison Break

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:一个n*m的矩阵,'F'是起点.机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所 ...

  10. light oj 1254 - Prison Break 最短路

    题目大意:n个点m条边的有向图,q次询问c,s,t,表示汽车邮箱容量为c,求从起点s到终点t的最小费用.汽车在每个点可以加任意的油,每个点的单位油价为a[i]. 题目思路:利用最小费优先队列优化最短路 ...

随机推荐

  1. HDU_1848_博弈,sg函数

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  2. Symbolicating Crash Reports With atos

    地址:0x1000e4000 + 49116 = 0x00000001000effdc都是运行时地址: 0x1000e4000:基址偏移后的地址: 0x100000000: 共知基址:各个环境都知道, ...

  3. sqlserver 2014 删除主键约束

    truncate table menu SELECT * FROM sys.foreign_keys WHERE referenced_object_id=OBJECT_ID('menu'); --找 ...

  4. CAD在网页中如何设置实体闪烁?

    主要用到函数说明: MxDrawXCustomFunction::Mx_TwinkeEnt 闪烁实体.详细说明如下: 参数 说明 McDbObjectId id 被闪烁的实体对象id LONG lCo ...

  5. Promise嵌套问题/async await执行顺序

    /* 原则: 执行完当前promise, 会把紧挨着的then放入microtask队尾, 链后面的第二个then暂不处理分析, */ 一. new Promise((resolve, reject) ...

  6. UVA1001 Say Cheese(Dijkstra或Floyd)

    题目链接:UVA1001 题意:在一个巨大奶酪中的A要以最短的时间与B相遇.在奶酪中走一米的距离花费的时间是10s,而奶酪中有许多洞,穿过这些洞的时间是0s.给出A.B以及各个洞的坐标,求最短的时间. ...

  7. JAVA经典题--死锁案例

    死锁原理: 两个线程相互等待对方释放同步监视器 例子程序: public class TestDeadLock implements Runnable { public int flag = 1; s ...

  8. JS练习:定时器--背景颜色交替变换

    代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UT ...

  9. 2.2sklearn.preprocessing.PolynomialFeatures生成交叉特征

    sklearn.preprocessing.PolynomialFeatures原文 多项式生成函数:sklearn.preprocessing.PolynomialFeatures(degree=2 ...

  10. 00.pip安装包

    pip安装更换镜像源 pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com pip导出和导入 ...