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

题目链接:

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. JavaScript:颜色辨别

    <script> //参考文章:http://www.cnblogs.com/xuechenlei/p/5940729.html //游戏页面:http://www.webhek.com/ ...

  2. Spring Boot 集成 JWT 实现单点登录授权

    使用步骤如下:1. 添加Gradle依赖: dependencies { implementation 'com.auth0:java-jwt:3.3.0' implementation('org.s ...

  3. 关于预测io调用的思考

    什么是预测io 预测io是linux2.6版本内核调用默认的调用程序,对应用程序进行跟踪,统计应用程序使用io情况,在读操作返回之前先停顿6ms时间(linux默认时间),如果这期间有读操作过来,可以 ...

  4. JavaScript初步学习----基本使用,简单事件,修改样式,数据类型

    JavaScript基本使用 JavaScript原名叫livescript,是一门动态类型,弱类型基于原型的脚本语言   用于页面特效,前后交替,后台开发(node)   JavaScript写在s ...

  5. 2.1.4、SparkEnv中创建BroadcastManager

    Broadcast是分布式的数据共享,由BroadcastManager负责管理其创建或销毁.Broadcast一般用于处理共享的配置文件.通用Dataset.常用数据结构 通过SparkContex ...

  6. Flume基本概念

    1         Apache Flume 1.1         概述 Flume是Cloudera提供的一个高可用,高可靠的,分布式的海量日志采集.聚合和传输的软件. Flume的核心是把数据从 ...

  7. Network Saboteur POJ 2531 回溯搜索

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12886   Accepted: 6187 Description A un ...

  8. [bzoj4066/2683]简单题_KD-Tree

    简单题 bzoj-4066 题目大意:n*n的棋盘,开始为均为0,支持:单点加权值,查询矩阵权值和,强制在线. 注释:$1\le n\le 5\cdot 10^5$,$1\le m \le 2\cdo ...

  9. Spring MVC-控制器(Controller)-参数方法名称解析器(Parameter Method Name Resolver )示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_parametermethodnameresolver.htm 说明:示例基于Sp ...

  10. Spring MVC-表单(Form)标签-列表框(Listbox)示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_listbox.htm 说明:示例基于Spring MVC 4.1.6. 以下示例 ...