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

题目链接:

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. acedinitget

    // 提示用户选择选择方式 acedInitGet(0, _T("W CP")); int nRs = acedGetKword(_T("\n请输入关键字确定选择方式[窗 ...

  2. react 子组件调用父组件方法

    import React from 'react'import '../page1/header.css'import { Table } from 'antd'import Child from ' ...

  3. [luogu2591 ZJOI2009] 函数

    传送门 Solution 画图找规律.. Code //By Menteur_Hxy #include <cstdio> #define min(a,b) ((a)>(b)?(b): ...

  4. Maven中更改默认JDK版本

    只要在settings.xml文件中加上如下标签即可.(我这里是默认的1.7版本) <profiles> <profile> <id>jdk-1.7</id& ...

  5. yum更换国内源及yum下载rpm包

    一.yum更换国内源 运维开发技术交流群欢迎大家加入一起学习(QQ:722381733) 1.前往yum文件路径地址 [root@web1 ~]# cd /etc/yum.repos.d/ [root ...

  6. HTML学习笔记之HTML5新特性

    目录 1.拖放 2.画布 3.可伸缩矢量图形 4.地理定位 5.Web 存储 6.应用缓存 7.Web Worker 1.拖放 拖放是一种常见的特性,用于抓取对象以后拖到另一个位置,它是 HTML5 ...

  7. PAT 1057. Stack

    Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...

  8. hdu_1285_确定比赛名次_201312081335

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  9. 递归算法详细分析->C

    C通过运行时堆栈支持递归函数的实现.递归函数就是直接或间接调用自身的函数.     许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的<C语言程序设计> ...

  10. Windows超级卸载工具Total Uninstaller,能完全卸载.NET Framework

    https://github.com/tsasioglu/Total-Uninstaller