美文网首页信息学竞赛题解(IO题解)
3190: [JLOI2013]赛车(离散化+栈)

3190: [JLOI2013]赛车(离散化+栈)

作者: AmadeusChan | 来源:发表于2018-10-17 12:02 被阅读0次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3190

    很弱的一道题:把所有赛车看成一条直线:y = vi * t + ki( t 表示时间 ),那么这道题便成了求存在t属于[0,正无穷)使得直线的y值在所有直线中最大(允许存在一样大的)的数目,那么把斜率升序排序,然后用个栈维护就可以了,注意点细节。(最开始没有排序WA了两次...QaQ...)

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
     
    using namespace std ;
     
    #define MAXN 10010
     
    struct Line {
        int k , b , t ;
        bool operator < ( const Line &a ) const {
            return k < a.k || ( k == a.k && b > a.b ) ;
        }
        bool operator == ( const Line &a ) const {
            return k == a.k && b == a.b ;
        }
    } line[ MAXN ] ;
     
    int Stack[ MAXN ] , top = 0 , ans[ MAXN ] , ansn = 0 , n ;
     
    struct Pos {
        double x , y ;
        Pos( double _x , double _y ) :x( _x ) ,y( _y ) {
        }
    };
     
    double Value( int a , double x ) {
        return line[ a ].k * x + line[ a ].b ;
    }
     
    Pos Cross( int a , int b ) {
        double x = double( line[ b ].b - line[ a ].b ) / double( line[ a ].k - line[ b ].k ) ;
        return Pos( x ,Value( a , x ) ) ;
    }
     
    int main(  ) {
        scanf( "%d" , &n ) ;
        for ( int i = 0 ; i ++ < n ; )scanf( "%d" , &line[ i ].b ) ;
        for ( int i = 0 ; i ++ < n ; )scanf( "%d" , &line[ i ].k ) ;
        for ( int i = 0 ; i ++ < n ; ) line[ i ].t = i ;
        sort( line + 1 , line + n + 1 ) ;
        for ( int i = 0 ; i ++ < n ; ) {
            if ( top && line[ Stack[ top ] ].k == line[ i ].k ) continue ;
            while ( top ) {
                Pos p =Cross( i , Stack[ top ] ) ;
                if ( p.x < 0 ) top -- ; else
                if ( top > 1 &&Value( Stack[ top - 1 ] , p.x ) > p.y ) top -- ;
                else break ;
            }
            Stack[ ++ top ] = i ;
        }
        for ( int i = 0 ; i ++ < top ; ) {
            for ( int j = Stack[ i ] ; j <= n && line[ j ] == line[ Stack[ i ] ] ; j ++ ) ans[ ++ ansn ] = line[ j ].t ;
        }
        sort( ans + 1 , ans + ansn + 1 ) ;
        printf( "%d\n" , ansn ) ;
        for ( int i = 0 ; i ++ < ansn - 1 ; )printf( "%d " , ans[ i ] ) ;
        printf( "%d\n" , ans[ ansn ] ) ;
        return 0 ;
    }
    
    

    相关文章

      网友评论

        本文标题:3190: [JLOI2013]赛车(离散化+栈)

        本文链接:https://www.haomeiwen.com/subject/hcglzftx.html