• [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
    先对斜率排序(以从小到大为例)然后逐条判断如图

    前四条线符合,判断第五条,算出第五条线与第四条线交点的横坐标X1和第四条线和第三条线交点的横坐标X2,若X1<=X2,说明第四条线被第三条线和第五条线覆盖,删除第四条线,然后向前判断。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <iomanip>
    #include <cmath>
    #include <cassert>
    #include <ctime>
    #include <cstdlib>
    #include <map>
    #include <set>
    using namespace std;
    #pragma comment(linker, "/stck:1024000000,1024000000")
    #define lowbit(x) (x&(-x))
    #define max(x,y) (x>=y?x:y)
    #define min(x,y) (x<=y?x:y)
    #define MAX 100000000000000000
    #define MOD 1000
    #define pi acos(-1.0)
    #define ei exp(1)
    #define PI 3.1415926535897932384626433832
    #define ios() ios::sync_with_stdio(true)
    #define INF 1044266558
    #define mem(a) (memset(a,0,sizeof(a)))
    typedef long long ll;
    struct node
    {
        int id;
        double k,y;
    }e[50006],q[50006];
    int n,cnt=0,vis[50006];
    bool cmp(node a,node b)
    {
        return a.k<b.k || a.k==b.k&&a.y>b.y;
    }
    double cal(node a,node b)
    {
        return (b.y-a.y)/(a.k-b.k);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            e[i].id=i;
            scanf("%lf%lf",&e[i].k,&e[i].y);
        }
        sort(e+1,e+1+n,cmp);
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            if(cnt==0) q[++cnt]=e[i];
            else if(e[i].k==q[cnt].k) {vis[e[i].id]=1;continue;}
            else 
            {
                while(1)
                {
                    if(cnt==1){q[++cnt]=e[i];break;}
                    double x1=cal(e[i],q[cnt]);
                    double x2=cal(q[cnt],q[cnt-1]);
                    if(x1<=x2) vis[q[cnt].id]=1,cnt--;
                    else {q[++cnt]=e[i];break;}
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]) printf("%d ",i);
        }
        return 0;
    }
  • 相关阅读:
    从零开始系统深入学习android(实践让我们开始写代码Android框架学习7.App Widgets)
    用才智征服天下,用信誉赢得未来
    微众时代看网络营销
    营销不是传奇,欠的只是方法
    名扬天下,从这里出发
    【缅怀妈妈系列诗歌】之二十六:贺诞母亲
    营销密码,带你走进神奇地带
    打造“80后”第一营销品牌
    如果有一天
    把你写进诗里
  • 原文地址:https://www.cnblogs.com/shinianhuanniyijuhaojiubujian/p/8259289.html
Copyright © 2020-2023  润新知