BZOJ 1007 HNOI 2008 水平可见直线 计算几何+栈
题目大意:给出一些笛卡尔系中的一些直线,问从(0,+∞)向下看时能看到哪些直线。
思路:半平面交可做,可是显然用不上。
类似于求凸包的思想,维护一个栈。
先将全部直线依照k值排序。然后挨个压进去,遇到有前一个交点被挡住的话就先弹栈。
比較闹心的是去重。我的方法是压栈之前先去重,然后在处理。
CODE:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50010
#define EPS 1e-5
using namespace std; inline bool dcmp(double a,double b); struct Point{
double x,y; Point(double _ = 0,double __ = 0):x(_),y(__) {}
Point operator +(const Point &a)const {
return Point(x + a.x,y + a.y);
}
Point operator -(const Point &a)const {
return Point(x - a.x,y - a.y);
}
};
struct Line{
double k,b;
int _id; bool operator <(const Line &a)const {
if(dcmp(k,a.k)) return b < a.b;
return k < a.k;
}
}line[MAX],_line[MAX]; int lines;
int top;
Line *stack[MAX];
Point intersection[MAX]; bool ans[MAX]; inline Point GetIntersection(const Line &l1,const Line &l2);
inline bool Under(const Line &l,const Point &p); int main()
{
cin >> lines;
for(int i = 1;i <= lines; ++i) {
scanf("%lf%lf",&line[i].k,&line[i].b);
line[i]._id = i;
}
sort(line + 1,line + lines + 1);
int cnt = 0;
for(int i = 1;i <= lines; ++i) {
if(dcmp(line[i].k,line[i + 1].k)) continue;
_line[++cnt] = line[i];
}
stack[++top] = &_line[1];
stack[++top] = &_line[2];
intersection[top - 1] = GetIntersection(_line[1],_line[2]);
for(int i = 3;i <= cnt; ++i) {
if(i != cnt && _line[i].k == _line[i + 1].k) continue;
while(top > 1 && Under(_line[i],intersection[top - 1])) --top;
stack[++top] = &_line[i];
intersection[top - 1] = GetIntersection(*stack[top],*stack[top - 1]);
}
for(int i = 1;i <= top; ++i)
ans[stack[i]->_id] = true;
for(int i = 1;i <= lines; ++i)
if(ans[i]) printf("%d ",i);
return 0;
} inline bool dcmp(double a,double b)
{
return fabs(a - b) < EPS;
} inline Point GetIntersection(const Line &l1,const Line &l2)
{
Point re;
re.x = (l2.b - l1.b) / (l1.k - l2.k);
re.y = re.x * l1.k + l1.b;
return re;
} inline bool Under(const Line &l,const Point &p)
{
if(l.k * p.x + l.b > p.y || dcmp(l.k * p.x + l.b,p.y)) return true;
return false;
}
BZOJ 1007 HNOI 2008 水平可见直线 计算几何+栈的更多相关文章
- 【BZOJ 1007】 [HNOI2008]水平可见直线
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线: ...
- 【BZOJ 1007】 [HNOI2008]水平可见直线
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1007 [题意] [题解] 这个人讲得很好 http://blog.csdn.net/o ...
- BZOJ 1007 水平可见直线 | 计算几何
BZOJ 1007 水平可见直线 题面 平面直角坐标系上有一些直线,请求出在纵坐标无限大处能看到哪些直线. 题解 将所有直线按照斜率排序(平行的直线只保留最高的直线),维护一个栈,当当前直线与栈顶直线 ...
- bzoj1007 [HNOI2008]水平可见直线——单调栈
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1007 可以把直线按斜率从小到大排序,用单调栈维护,判断新直线与栈顶的交点和栈顶与它之前直线的 ...
- BZOJ1007: [HNOI2008]水平可见直线(单调栈)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8638 Solved: 3327[Submit][Status][Discuss] Descripti ...
- bzoj 1007 : [HNOI2008]水平可见直线 计算几何
题目链接 给出n条直线, 问从y轴上方向下看, 能看到哪些直线, 输出这些直线的编号. 首先我们按斜率排序, 然后依次加入一个栈里面, 如果刚加入的直线, 和之前的那条直线斜率相等, 那么显然之前的会 ...
- BZOJ 1007 [HNOI2008]水平可见直线 ——计算几何
用了trinkle的方法,半平面交转凸包. 写了一发,既没有精度误差,也很好写. #include <map> #include <ctime> #include <cm ...
- BZOJ1007:[HNOI2008]水平可见直线(计算几何)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...
- [bzoj 1004][HNOI 2008]Cards(Burnside引理+DP)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 分析: 1.确定方向:肯定是组合数学问题,不是Polya就是Burnside,然后题目上 ...
随机推荐
- BZOJ 3211 线段树+并查集
思路: 我们很容易发现 一个数开根号 开几(很小)次 就到了1 1 再怎么开 都是1 由于这个性质 我们就可以用并查集 了 //By SiriusRen #include <cmath> ...
- Codeforces 344C Rational Resistance
Description Mad scientist Mike is building a time machine in his spare time. To finish the work, he ...
- div动态加载页面
div动态加载页面 /* /// method 1 var url="<%=basePath%>/qne.do?p=pessegerCountSet"; $.post( ...
- VirtualBox内刚刚安装完CentOS6.9和7系统,无法调整屏幕的分辨率,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。
VirtualBox内刚刚安装完CentOS6.9和7系统,无法调整屏幕的分辨率,也无法设置共享文件夹.解决的方法就是安装VirtualBox客户端增强包. 1.若直接安装客户端增强包会得到如下提示: ...
- Mark Compact GC (Part one: Lisp2)
目录 什么是GC 标记-压缩算法 Lisp2 算法的对象 概要 步骤 步骤一:设定forwarding指针 步骤二:更新指针 步骤三:移动对象 优缺点 什么是GC 标记-压缩算法 需要对标记清除和GC ...
- R与并行计算
本文在Creative Commons许可证下发布 什么是并行计算? 并行计算,准确地说应该包括高性能计算机和并行软件两个方面.不过,近年来随着个人PC机,廉价机群,以及各种加速卡(NVIDIA GP ...
- 紫书 例题 9-12 UVa 12186 (树形dp)
这道题还是比较简单的,对于当前节点,算出每个儿子需要的人数 然后再算出当前节点需要多少个人数,然后排个序加上去就好了. #include<cstdio> #include<vecto ...
- hdu 5312 Sequence(数学推导——三角形数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others) ...
- [Python] Python list slice syntax fun
# Python's list slice syntax can be used without indices # for a few fun and useful things: # You ca ...
- Linux经常使用命令(十六) - whereis
whereis命令仅仅能用于程序名的搜索(程序安装在哪?).并且仅仅搜索二进制文件(參数-b).man说明文件(參数-m)和源码文件(參数-s). 假设省略參数,则返回全部信息. 和find相比.wh ...