zoukankan      html  css  js  c++  java
  • BZOJ 1007 水平可见直线 | 计算几何

    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;
    }
    
  • 相关阅读:
    C#编程技巧之钩子函数的使用——SetWindowsHookEx
    JSON(Ajax)和JsonP
    C#对象与方法
    C#数据类型
    事务处理
    面向对象之继承与多态
    C#编程语言简介
    <转>成员函数的重载、覆盖与隐藏
    视图、索引
    C#方法
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/BZOJ1007.html
Copyright © 2011-2022 走看看