码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1007 水平可见直线 | 计算几何

时间:2017-12-15 15:40:45      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:obj   name   namespace   cpp   using   algo   include   main   证明   

BZOJ 1007 水平可见直线

题面

平面直角坐标系上有一些直线,请求出在纵坐标无限大处能看到哪些直线。

题解

将所有直线按照斜率排序(平行的直线只保留最高的直线),维护一个栈,当当前直线与栈顶直线的交点在栈顶两条直线的交点的左边,则弹出栈顶元素。可以画图证明这是正确的(因为我们要维护一个下凸的图形)。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 50005;
int n, top, idx, ans[N];
struct Line {
    int id;
    double k, b;
    bool operator < (const Line &obj) const{
    return k != obj.k ? k < obj.k: b < obj.b;
    }
} raw[N], line[N], stk[N];
double getx(const Line &A, const Line &B){
    return (B.b - A.b) / (A.k - B.k);
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    raw[i].id = i, scanf("%lf%lf", &raw[i].k, &raw[i].b);
    sort(raw + 1, raw + n + 1);
    line[idx = 1] = raw[1];
    for(int i = 2; i <= n; i++)
    line[raw[i].k == raw[i - 1].k ? idx: ++idx] = raw[i];
    for(int i = 1; i <= idx; i++){
    while(top > 1 && getx(line[i], stk[top]) <= getx(stk[top], stk[top - 1])) top--;
    stk[++top] = line[i];
    }
    for(int i = 1; i <= top; i++) ans[i] = stk[i].id;
    sort(ans + 1, ans + top + 1);
    for(int i = 1; i <= top; i++) printf("%d ", ans[i]);
    puts("");
    return 0;
}

BZOJ 1007 水平可见直线 | 计算几何

标签:obj   name   namespace   cpp   using   algo   include   main   证明   

原文地址:http://www.cnblogs.com/RabbitHu/p/BZOJ1007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!