ICPC 2019マレーシア国立H题

問題の意味:n個の点を考えるとは、凸包を構成するこれらの点が決定され、その後出力反時計回り、q番目のクエリに加え、各バッグ凸面上の点かどうかを尋ねます。

ソリューション:2次元直接外積、凸包におけるN2の時間の複雑さを決定するために指しているかどうか、凸包裸のタイトル、私は15秒に、なぜこの質問を知らない、と私は、コードを実行しただけで15msの

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
ダブル EPS = 1E- 15 ;
ダブル PI = ACOS( - 1 )。
構造体のポイント{
     ダブルX、Y。
    点(二重 X = 0二重 Y = 0 )、X(x)、Y(Y){} 
}。
typedefのポイント・ベクトル。
ベクトル演算子 +(ベクトルA、ベクトルB){ 戻りベクトル(A.x + BX、A.y + B.y);} 
ベクトル演算子 - (ベクトルA、ベクトルBを){ 戻りベクトル(AX-BX、Ay- により)を、 } 
ベクトル演算子 *(ベクトルA、ダブル B){ 戻りベクトル(AX * B、Ayの* Bを);} 
ベクトルオペレータ /(ベクトルA、ダブル {B)戻りベクトル(AX / B、Ayの/ B);}
 int型 DCMP(ダブルX){
     場合(ファブ(X)<EPS)戻り 0 ;
    他に 返すのx < 0 - ?11 ; 
} 
ブール 演算子 <(CONSTポイント&、constのポイント&B){
     戻り DCMP(AX-BX)< 0を||(DCMP(AX-BX)== 0 && DCMP(AY-によって)< 0 )。
} 
ブール 演算子 ==(constのポイント&、constのポイント&B){
     戻り DCMP(AX-BX)== 0 && DCMP(AY-によって)== 0 
} 
ダブルクロス(ベクトルA、ベクトルB){
     戻り BY-Ayの*斧*をBxを、
} 
二重ドット(ベクトルA、ベクトルB){
     戻りアックス* B.x + Ayの* によってと、
} 
ベクトル回転(ベクトルA、ダブルRAD)は{
     戻りベクトル(AX * COS(RAD)-Ay * SIN(RAD)、Axは* SIN(RAD)+をAyの*COS(RAD)); 
} 
int型(ポイント* P、tubaoをINT N-、ポイント*のCH){ // 凸包を見つけ、アレイの凸包長返す 
    ソート(P、P + N-)を、
     INT、M = 0 ;
     のためにINT = I 0、I <N - 、I ++ ){
         ながら(M> 1 &&クロス(CH [M- 1 ] -CH [M- 2 ]、P [I] -CH [M- 2 ])<= 0)M- - ; 
        CH [M ++] = P [I]; 
    } 
    int型 K = M;
     のためのINT I = N- 2 ; I> =0 ; i-- ){
         ながら(M> K &&クロス(CH [M- 1 ] -CH [M- 2 ]、P [i]は、-CH [M- 2 ])<= 0)M-- 
        CH [M ++] = P [i]は、
    } 
    であれば(N> 1)M-- リターンメートル。
} 
ボイド READP(ポイント&A){ 
    scanf関数(" %のLFの%のLF "、&​​A.x、&A.y)。
} 
BOOL onsegment(点P、点A1、点A2){
     場合(P == A1 || P == A2)を返す リターンDCMP(クロス(A1-P、A2-P))== 0 && DCMP(ドット(A1-P、A2-P))< 0 
} 
BOOL segmentcross(点A1、点A2、点B1、点B2){
     場合(A1 == B1 || A1 == B2 || A2 == B1 || A2 == b2)は戻り 二重 C1 =クロス(A2-A1、B1-A1)、C2 =クロス(A2-A1、B2- A1)、
           C3 =クロス(B2-B1、A1-B1)、C4 =クロス(B2-B1、A2- B1);
    戻り DCMP(C1)* DCMP(C2)< 0 && DCMP(C3)* DCMP(C4)< 0 
} 
int型 intubao(ポイント*のCH、int型 N、点p){ // 判断P点是否在凸包内
    のベクトルA、B。
    int型のフラグ=0 ;
     のためのint型 I = 0 ; I <N-Iが++ ){ 
        A = CH [(私は+ 1)%N-] - CH [I]; 
        B = P- CH [I];
         / * IF(onsegment(P、 CH [i]は、CHの[( I + 1)%のN])){// 外部考えこの問題は、前記凸包上の凸包点
            フラグ= -1で、
            BREAK; 
        } * / 
        IF(クロス(A 、B)> 0 ){ 
            フラグに ++ ; 
        } 
    } 
    IF(フラグに== - 1。フラグに|| == N-)リターン 1。;
     戻り 0 ; 
}
INT T、N、Q、M。
点p1 [ 10005 ]、CH1 [ 10005 ]。
構造体ノード{
     ダブルX、Y。
} G [ 1005 ]。
INT メイン(){ 
    scanf関数(" %のD "、&T)。
    int型加瀬= 0 ;
    一方、(T-- ){ 
        scanf関数(" %d個の%のD "、&​​N、&Q)。
        以下のためにint型 i = 0 ; iがn <; iは++ ){ 
            READP(P1 [I])。
        } 
        int型 M1 =tubao(P1、N、CH1)。
        以下のためにint型 I = 1 ; I <= Q; iが++ ){ 
            scanf関数(" %のLFの%のLF "、&​​G [i]は.X、&G [i]が.Y)。
        } 
        のprintf(" ケース%Dを\ n "、++ 加瀬)。
        以下のためにint型私= 0 ; iがM1を<; Iは++ ){ 
            のprintf(" %D%D \ n "、(INT)CH1 [I] .X、(INT )CH1 [I] .Y)。
        } 
        のprintf(" %D%D \ n "、(INT)CH1 [0 ] .X、(INT)CH1 [ 0 ]・Y)
        以下のためにint型 iは= 1 ; I <= Q iは++ ){ 
            点T。
            TX = G [i]は.X。
            TY = G [i]が.Y。
            printf(" %dの%のD "、(INT)TX、(INT )TY)。
            もし(intubao(CH1、M1、T))のprintf(" 安全ではありません\ nは!" );
            のprintf(" 安全である\ nは!" ); 
        } 
        のprintf(" \ nを" ); 
    } 
}

 

おすすめ

転載: www.cnblogs.com/ccsu-kid/p/11073903.html