zoukankan      html  css  js  c++  java
  • luogu P3194 [HNOI2008]水平可见直线 |单调栈

    题目描述

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

    输入格式

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

    输出格式

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


    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=5e4+10;
    #define int long long
    #define db double
    inline void read(int&x){
        x = 0;char c;int sign = 1;
        do{ c = getchar(); if(c == '-') sign = -1; }while(c < '0' || c>'9');
        do{ x = x*10 + c -'0';c = getchar(); }while(c <= '9' && c >= '0');
        x *= sign;
    }
    struct node{
    	int A,B,id;	
    }e[N];
    const bool cmp(node t1,node t2){
    	return (t1.A^t2.A) ? t1.A<t2.A : t1.B>t2.B ;
    }
    inline db sol(int i,int j){return (db)(e[i].B-e[j].B)/(db)(e[j].A-e[i].A);}
    int n,st[N],ans[N],top;
    signed main(){
    	read(n);
    	for(int i=1;i<=n;i++)read(e[i].A),read(e[i].B),e[i].id=i;
    	sort(e+1,e+1+n,cmp);
    	for(int i=1;i<=n;i++){
    		if(e[i].A==e[i-1].A&&i!=1)continue;
    		while(top>1&&sol(st[top],i)<=sol(st[top],st[top-1]))top--;
    		st[++top]=i;
    		ans[top]=e[i].id;
    	}
    	sort(ans+1,ans+1+top);
    	for(int i=1;i<=top;i++)printf("%lld ",ans[i]);
    }
    
  • 相关阅读:
    fianl关键字和static关键字
    jdk的安装
    this关键字和super关键字
    Java 数组
    网络通信知识复习
    Linux 下执行本目录的可执行文件(命令)为什么需要在文件名前加“./”
    CentOS 7 下安装 teamviewer 13
    我的 Putty 配色方案
    在 Mac OS X 下,如何向 sudoers 文件添加新用户
    Windows 7 下使用 pandoc 转换文档格式
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12968331.html
Copyright © 2011-2022 走看看