zoukankan      html  css  js  c++  java
  • bzoj 3190 维护栈

      我们可以将每一辆赛车看成一条直线,斜率为速度,纵截距为初始位置,那么问题就转化为求这n条直线处于最上面的直线。最上面是指在坐标系中,假设从x轴向下看,能看到的直线,只露一个点也算能看见。那么就类似水平可见直线这道题了。先按照斜率排序,然后维护直线的栈就行了。

      

    /**************************************************************
        Problem: 3190
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:84 ms
        Memory:548 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n                       :longint;
        a, b, num               :array[0..10010] of longint;
        quea, queb              :array[0..10010] of longint;
        tot                     :longint;
        quex                    :array[0..10010] of double;
        ans                     :array[0..10010] of longint;
        i, j                    :longint;
        flag                    :array[0..10010] of boolean;
        maxi                    :longint;
         
    procedure swap(var a,b:longint);
    var
        c                       :longint;
    begin
        c:=a; a:=b; b:=c;
    end;
         
    procedure qs(low,high:longint);
    var
        i, j, xx, yy            :longint;
    begin
        i:=low; j:=high; xx:=a[(i+j) div 2];
        yy:=b[(i+j) div 2];
        while i<j do
        begin
            while (a[i]<xx) or (a[i]=xx) and (b[i]>yy) do inc(i);
            while (a[j]>xx) or (a[j]=xx) and (b[j]<yy) do dec(j);
            if i<=j then
            begin
                swap(a[i],a[j]);
                swap(b[i],b[j]);
                swap(num[i],num[j]);
                inc(i); dec(j);
            end;
        end;
        if i<high then qs(i,high);
        if j>low then qs(low,j);
    end;
         
    procedure insert(i:longint);
    var
        k                       :longint;
        x                       :double;
    begin
        if a[i]=quea[tot] then exit;
        if tot>1 then
        begin
            x:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
            while (tot>1) and (x<quex[tot]) do
            begin
                dec(tot);
                x:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
            end;
        end;
        inc(tot);
        quea[tot]:=a[i];
        queb[tot]:=b[i];
        quex[tot]:=(queb[tot-1]-b[i])/(a[i]-quea[tot-1]);
        ans[tot]:=num[i];
    end;
         
    begin
        read(n);
        for i:=1 to n do read(b[i]);
        for i:=1 to n do read(a[i]);
        maxi:=0;
        for i:=1 to n do if b[i]>b[maxi] then maxi:=i; 
        flag[maxi]:=true;
        for i:=1 to n do if b[i]=b[maxi] then flag[i]:=true;
        for i:=1 to n do num[i]:=i;
        qs(1,n);
        quea[1]:=a[1]; queb[1]:=b[1]; 
        quex[1]:=-maxlongint; ans[1]:=num[1];
        tot:=1;
        for i:=2 to n do insert(i);
        for i:=1 to tot do if quex[i]>=0 then break;
        for j:=i to tot do flag[ans[j]]:=true;
        qs(1,n);
        for i:=1 to n do
            if flag[i] then
            begin
                j:=i-1;
                while (a[j]=a[i]) and (b[j]=b[i]) do
                begin
                    flag[j]:=true;
                    dec(j);
                end;
                j:=i+1;
                while (a[j]=a[i]) and (b[j]=b[i]) do
                begin
                    flag[j]:=true;
                    inc(j);
                end;
            end;
        tot:=0;
        for i:=1 to n do if flag[i] then inc(tot);
        writeln(tot);
        for i:=1 to n do if flag[i] then break;
        write(i);
        for j:=i+1 to n do if flag[j] then write(' ',j);
        writeln;
    end.
  • 相关阅读:
    PHP 开发 APP 接口 学习笔记与总结
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 41 缺失的第一个正数
    Java实现 LeetCode 41 缺失的第一个正数
    Java实现 LeetCode 41 缺失的第一个正数
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3513989.html
Copyright © 2011-2022 走看看