zoukankan      html  css  js  c++  java
  • bzoj 1007: [HNOI2008]水平可见直线

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 5308  Solved: 1990
    [Submit][Status][Discuss]

    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
    题解:

      先按斜率排序,再将最小的一条线入栈,然后依次处理2~N条线,如果第i条直线与stack[top]直线的交点在stack[top]和stack[top-1]直线度左边,则top--,具体可以画几条线模拟一下。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<vector>
     9 using namespace std;
    10 const double eps=1e-6;
    11 const int maxn=50010;
    12 struct bian{
    13     double k,b;
    14     int id;
    15 }str[maxn];
    16 int cmp(const bian &x1,const bian &x2){
    17     return x1.k<x2.k||(fabs(x1.k-x2.k)<eps&&x1.b<x2.b);
    18 }
    19 inline double crossx(int x1,int x2){
    20     return (str[x2].b-str[x1].b)/(str[x1].k-str[x2].k);
    21 }
    22 int stack[maxn],top;
    23 int N,ans[maxn];
    24 int main(){
    25     scanf("%d",&N);
    26     for(int i=1;i<=N;i++){
    27         scanf("%lf%lf",&str[i].k,&str[i].b);
    28         str[i].id=i;
    29     }
    30     sort(str+1,str+N+1,cmp);
    31     
    32     stack[++top]=1;
    33     for(int i=2;i<=N;i++){
    34         while(top!=0){
    35             if(fabs(str[i].k-str[stack[top]].k)<eps) top--;
    36             if((crossx(stack[top-1],i)<=crossx(stack[top-1],stack[top]))&&top>=2)
    37                 top--;
    38             else break;
    39         }
    40         stack[++top]=i;
    41     }
    42     for(int i=1;i<=top;i++) ans[str[stack[i]].id]=1;
    43     for(int i=1;i<=N;i++){
    44         if(ans[i]==1) printf("%d ",i);
    45     }
    46     return 0;
    47 }

     

  • 相关阅读:
    CEAA自动汇编脚本常用命令
    PIC之拉电流和灌电流
    CHARRANGE 结构
    汇编中的lodsb和stosb、lodsd和stosd指令
    汇编中的STOSB与STOSD指令
    汇编中的CLD指令
    SQL中distinct的用法
    SQL union介绍
    【项目排期】测试排期问题思考
    SQL join的介绍
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5243151.html
Copyright © 2011-2022 走看看