• [BZOJ1007](HNOI2008)水平可见直线(半平面交习题)


    Description

     在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.
        例如,对于直线:
        L1:y=x; L2:y=-x; L3:y=0
        则L1和L2是可见的,L3是被覆盖的.
        给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.

    Input

    第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi

    Output

    从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格

    Sample Input

    3
    -1 0
    1 0
    0 0

    Sample Output

    1 2

    分析

        半平面交的模板题。维护一个栈,把所有边按极角排序后依次插入,每次弹出所有可以被覆盖的直线。

     1 /**************************************************************
     2     Problem: 1007
     3     User: AsmDef
     4     Language: C++
     5     Result: Accepted
     6     Time:124 ms
     7     Memory:2496 kb
     8 ****************************************************************/
     9  
    10 //Asm.Def
    11 #include <cctype>
    12 #include <cstdio>
    13 #include <iostream>
    14 #include <cmath>
    15 #include <cstdlib>
    16 #include <algorithm>
    17 #include <assert.h>
    18 using namespace std;
    19 inline void getd(int &x){
    20     char c = getchar(); bool minus = 0;
    21     while(!isdigit(c) && c != '-')c = getchar();
    22     if(c == '-')minus = 1, c = getchar();
    23     x = c - '0';
    24     while(isdigit(c = getchar()))x = x * 10 + c - '0';
    25     if(minus)x = -x;
    26 }
    27 /*========================================================*/
    28 const int maxn = 50003;
    29 typedef long long LL;
    30 int N;
    31 struct Line{
    32     int id;
    33     int A, B;
    34 }line[maxn], St[maxn];
    35 bool operator < (const Line &a, const Line &b){return b.A > a.A;}
    36 inline void init(){
    37     getd(N);int i;
    38     for(i = 1;i <= N;++i)
    39         getd(line[i].A), getd(line[i].B), line[i].id = i;
    40     sort(line + 1, line + N + 1);
    41 }
    42 int it = 0;
    43 bool inS[maxn];
    44 inline void work(){
    45     int i;
    46     St[it++] = line[1];
    47     for(i = 2;i <= N;++i){
    48         if(line[i].A == St[it-1].A){
    49             if(line[i].B > St[it-1].B)
    50                 St[it-1] = line[i];
    51             else continue;
    52         }
    53         while(it > 1){
    54             LL a = (LL)(St[it-2].B - St[it-1].B) * (line[i].A - St[it-1].A);
    55             LL b = (LL)(St[it-1].B - line[i].B) * (St[it-1].A - St[it-2].A);
    56             if(a >= b)--it;
    57             else break;
    58         }
    59         St[it++] = line[i];
    60     }
    61     while(it)inS[St[--it].id] = 1;
    62     for(i = 1;i <= N;++i)
    63         if(inS[i]) printf("%d ", i);
    64 }
    65 int main(){
    66     #if defined DEBUG
    67     freopen("test""r", stdin);
    68     #endif
    69     init();
    70     work();
    71      
    72     return 0;
    73 }
    半平面交
  • 相关阅读:
    MySQL教程详解之存储引擎介绍及默认引擎设置
    最简单MySQL教程详解(基础篇)之多表联合查询
    Postfix常用命令和邮件队列管理(queue)
    备份数据库
    Docker基本命令
    ASCII码表
    mysql基本了解
    顺序对列,环形队列,反向链式栈
    进制的标识符
    多个线程的时间同步
  • 原文地址:https://www.cnblogs.com/Asm-Definer/p/4368032.html
Copyright © 2020-2023  润新知