• [HNOI2008]水平可见直线 半平面交


    求向直线们的俯视视角中可见的直线,以为是选最大最小斜率然后往中间放。。其实就是半平面交

    //#include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
    #define ll long long  
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++)  
      
    const int maxn=5e4+7;    
    const double eps=1e-6;
    
    struct Line{
    	double a,b;int id;
    }l[maxn];
    
    bool cmp(Line l1,Line l2){
    	if(fabs(l1.a-l2.a)<eps)return l1.b<l2.b;
    	return l1.a<l2.a;
    }
    
    Line st[maxn];bool ans[maxn];
    int top,n;
    
    double crossx(Line l1,Line l2){	//解出l1,l2交点横坐标
    	return (l2.b-l1.b)/(l1.a-l2.a);
    }
    
    void insert(Line a){
    	while(top){
    		if(fabs(st[top].a-a.a)<eps)top--;	//保留较高直线
    		else if(top>1 && crossx(a,st[top-1])<=crossx(st[top],st[top-1]))
    			top--;
    		else break;
    	}
    	st[++top]=a;
    }
    
    void work(){
    	for(int i=1;i<=n;i++)insert(l[i]);
    	for(int i=1;i<=top;i++)ans[st[i].id]=1;
    	for(int i=1;i<=n;i++)
    		if(ans[i])printf("%d ",i);
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%lf%lf",&l[i].a,&l[i].b);
    		l[i].id=i;
    	}
    	sort(l+1,l+n+1,cmp);
    	work();
    }


  • 相关阅读:
    C++ 不用 < > 与 : ?运算符判断 a,b大小
    CentOS7 MariaDB10
    CentOS Linux 挂载NTFS
    Linux访问Windows共享
    Emacs配置与插件集记录
    驱动精妙耍流氓,强制安装"新毒霸"
    C# TextBox控件之大小写自动转换
    生活随笔
    显示外网IP
    MySql
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611229.html
Copyright © 2020-2023  润新知