問題の意味: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 - ?1:1 ; } ブール 演算子 <(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を" ); } }