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

    题目描述:
    在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条直线两两不重合.求出所有可见的直线.


    题解:

    一道很好的思维题。
    1.简单手画一下,能被看到的直线应该是所有直线一起围成的大凸包。
    2.由于是凸包,我们考虑将所有直线按斜率排序,从小到大依次加入到平面直角坐标系中。
    3.我们考虑一下新加入直线的情况:

    在这种情况中,我们可以看到新加入的红色直线与加入之前平面中斜率第二大的直线的交点位于先前第一大与第二大之左,显然,这就会挡住平面中斜率第二大的直线,我们就将该直线弹出,直到找到一个交点在新加入直线的交点左侧。
    对于整个过程,直线的斜率单调递增,交点横坐标也单调递增,直接用单调栈维护即可。
    时间复杂度为 $O(n)$

    Code:

    #include<cstdio>
    #include<algorithm>
    #include<string>
    using namespace std;
    void setIO(string a){
    	freopen((a+".in").c_str(),"r",stdin);
    }
    const int maxn=100000+5;
    struct Line{
    	double slope, y;
    }line[maxn];
    int arr[maxn],ans[maxn],S[maxn],top;
    bool cmp(int i,int j){
    	if(line[i].slope==line[j].slope) return line[i].y>line[j].y;
    	return line[i].slope<line[j].slope;
    }
    double get(int i,int j){
    	return (line[i].y-line[j].y)/(line[j].slope-line[i].slope);
    }
    int main(){
    	//setIO("input");
    	int n;
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) {
    		scanf("%lf%lf",&line[i].slope,&line[i].y);
    		arr[i]=i;
    	}
    	sort(arr+1,arr+1+n,cmp);
        for(int i=1;i<=n;++i)
        {
        	int cur=arr[i];
      
        	if(line[cur].slope==line[arr[i-1]].slope && i!=1) continue;
        	while(top>1 && get(S[top],S[top-1])>=get(arr[i],S[top])) --top;
        	S[++top]=cur;
        	ans[top]=cur;
        }
        sort(ans+1,ans+1+top);
        for(int i=1;i<=top;++i) printf("%d ",ans[i]);
        return 0;
    }
    

      

  • 相关阅读:
    vue项目搭建
    js监听input输入框值的实时变化实例
    nodejs-Child Process模块
    nodejs-Express框架
    前端的存储技术cookie、sessionStorage、localStorage
    node.js之path
    css两列自适应布局的多种实现方式及原理。
    React jQuery公用组件开发模式及实现
    js创建对象的几种方式
    IE9 不F12打开控制台,代码不执行。打开后正常
  • 原文地址:https://www.cnblogs.com/guangheli/p/9879068.html
Copyright © 2011-2022 走看看