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

    BZOJ好像刷了十几道题了,虽然人这么弱,代码也丑,今天还是找几道有价值的整理一下算了。

    1193: [HNOI2008]水平可见直线

    Time Limit: 1 Sec  Memory Limit: 162 MB

    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
     
    先按斜率从小到大排序(相同斜率的,直接高的覆盖低的),则第一个一定看得到,1入队。
    然后根据对于当前队中最后一个元素i,找出其与i+1~n中交点最靠前(同样靠前就找斜率最大的)的点入队,直到不能放了为止。。。乱搞一通
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    #define N 50005
    int n,a[N][3];
    bool b[N];
    long long x1,y1,x2,y2;
    void Sort(int x,int y)
     {
        int l=x,r=y,mid=a[(x+y)/2][1],e;
        do
         {
            while (a[l][1]<mid) l++;
            while (a[r][1]>mid) r--;
            if (l<=r)
             {
                e=a[l][1];a[l][1]=a[r][1];a[r][1]=e;
                e=a[l][2];a[l][2]=a[r][2];a[r][2]=e;
                e=a[l][0];a[l][0]=a[r][0];a[r][0]=e;
                l++;r--;
             }
         } while (l<=r);
        if (l<y) Sort(l,y);
        if (x<r) Sort(x,r);
        return;
     }
    bool Cpr(long long x,long long y,long long z)
     {
        x1=a[z][2]-a[x][2];
    y1=a[x][1]-a[z][1];
    x2=a[z][2]-a[y][2];
    y2=a[y][1]-a[z][1]; if (y1<0) { x1=-x1;
    y1=-y1; } if (y2<0) { x2=-x2;
    y2=-y2; } if (x1*y2<x2*y1)
    return true; if (x1*y2==x2*y1&&a[x][1]>a[y][1])
    return true; return false; } int main() { long long i,j,k,l,q,w,e,t; memset(a,0,sizeof(a));memset(b,0,sizeof(b)); scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d%d",&a[i][1],&a[i][2]); a[i][0]=i; } Sort(1,n); q=1; for (i=2;i<=n;i++) { if (a[q][1]<a[i][1]) { q++;
    a[q][0]=a[i][0];
    a[q][1]=a[i][1];
    a[q][2]=a[i][2]; }else if (a[q][2]<a[i][2]) { a[q][0]=a[i][0];
    a[q][1]=a[i][1];
    a[q][2]=a[i][2]; } } n=q;
    b[a[1][0]]=1; t=2; while (t<=n) { q=t; for (i=t+1;i<=n;i++) if (Cpr(i,q,t-1))
    q=i; b[a[q][0]]=1;
    t=q+1; } for (i=1;i<=N;i++) if (b[i])
    printf("%d ",i); printf("\n"); return 0; }
  • 相关阅读:
    c内存结构
    Linux普通文件和设备的异同点
    二分查找在字符串中的应用范例
    快排的一种相当简单但不算最快的实现方式
    C程序的存储空间布局
    exit与_exit
    /proc文件系统
    Linux下监控磁盘空间的四个命令
    linux下监控进程需掌握的四个命令
    linux终端下文件不同颜色的含义
  • 原文地址:https://www.cnblogs.com/HJWJBSR/p/4149724.html
Copyright © 2011-2022 走看看