件名の説明:
ソリューション:
計算幾何学、外積の向きを決定します。
そして、全体の二分法をすることができます。
#include <cmath> の#include <ベクトル> の#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> 使用して 名前空間STDを、 const int型 N = 5050 ; constの ダブル EPS = 1E- 8 ; 構造体のポイント { ダブルX、Y。 ポイント(){} 点(ダブル X、ダブルY):X(X)、Y(Y){} ポイント演算子 - (CONSTポイント&A)のconst { 返す点を(xa.x、Y-AY);} ダブル 演算子 ^(CONSTポイント&A)のconst { リターンのx *のAY-Y * AX;} }。 typedefのポイント・ベクトル。 構造体のライン { 点p; ベクトルv。 ライン(){} 線(点P、ベクトルv):P(P)、V(V){} }。 線S [N]; INTのN、M。 ダブルX_1、Y_1、X_2、Y_2。 INT DCMP(ダブルX) { 場合(ファブ(X)<= EPS)戻り 0 ; 返すのx> 0?1: - 1; } BOOL Onleft(ラインL、点P) { 戻り DCMP(LV ^(pl.p))> 0 。 } ボイド DV(int型 L、int型の R、ベクトル<ポイント>・VE) { 場合(L == R) { のprintf(" %のD:%Dを\ n " 、L、ve.size())。 返します。 } INT半ば=((L + R)>> 1)+ 1 。 ベクトル <ポイント> VL、VR; 以下のための(int型 I = 0、LIM =(int型)ve.size(); iは<LIM; iは++ ) 場合(Onleft(S [中間]は、VEの[I]))vl.push_back(VEの[I])。 他vr.push_back([i]のVE); DV(L、ミッド - 1 、VL)。 DV(MID、R、VR)。 } int型のmain() { 一方(scanf関数(" %D%D%LF%LF%LF%LF "、&N、&M、&X_1、&Y_1、&X_2、&Y_2)== 6 ) { ダブルX、Y。 以下のために(int型私= 1 ; iが<= N; iが++ ) { scanf関数(" %のLFの%のLF "、およびX&Y)。 S [i]は =行(ポイント(Y、Y_2)、点(x、Y_1) - ポイント(Y、Y_2))。 } ベクトル <ポイント> V0。 以下のために(int型 I = 1 ; I <= M; iは++ ) { scanf関数(" %のLFの%のLF "、およびX&Y)。 v0.push_back(点(x、y))。 } DV(0 、N、V0)。 プット("" ); } 戻り 0 。 }