問題の意味:元々凸多角形の爪やロープ、ロープで区切らその後、爪が残っている爪が元の凸多角形を決定することができるかどうかを決定する、失っています。
変換:条件が満たさ:残りの釘は凸包構成することができ、そして各側面は、少なくとも3つの爪を有し、残りの爪少なくとも6、凸包の少なくとも3つの頂点。
アルゴリズム:; //データ範囲が1000であり、n ^ 2凸包構造は、各力の側面は、三点があるか否かを判断します
凸状のパッケージを感謝しました:
#include <iostreamの> する#include <cmath> の#include <アルゴリズム> の#include <cstdioを> 使用して 名前空間STD; のconst int型 MAXN = 1010 ; // これは、RTは、本明細書チェックポイントの数であり、 CONST ダブル PI = ACOSは( - 1.0 ); // 精度 ダブル EPS = 1E- 。8 ; // 避ける-0.00場合、EPSの最後の増加 // 精度比較 INT SGN(ダブルX) { IF(FABS(X)<= EPS)戻り 0 ; IF(X < 0)リターン - 1。; リターン 1 ; } // 点パッケージ 構造体のポイント { ダブルX、Y、 ポイント(){} // 割り当て ポイント(ダブル _x、ダブル_y) { X = _x; Y = _y; } // ポイント減算 ポイント演算子 - (CONST点B&)のconst { 戻り点(xb.x、Y- によって); } // 内積 二重 演算子 *(CONSTポイントB&)のconst { 戻り * X + Yをb.x によって; } // 外積 ダブル 演算子 ^(CONST ポイントB&)のconst { 戻り副X * Y *をBX; } }; // 包装ラインの 構造体のライン { ポイントS、E、 ライン(){} 線(点_s、ポイント_E) { S = _s; E = _E; } // 平行と交差する出力一致判定交差点 @直線が交差すると決意を重複なく、線分、 点演算子&(CONSTライン&B)のconst { ポイントRES = BS; IF(SGN((ES)^(BE-BS))== 0 ) { IF(SGN((ES) ^(eb.e))== 0 ) { // 一致 戻り点(0、0 ); } 他 { // 平行 リターンポイント(0、0 ); } } ダブル T =((ES)^(SBを。 S))/((ES) ^(BE-BS)); res.x + =(のBEx-BSX)* T; res.y + =(ベイ-BSY)* T; 戻りRESを; } }; // ベクトル外積 ダブルxmult(点P0、P1点、 P2点) { リターン(P0-P1)^(P2- P1); } // 線分を線分が非厳密に交差し、trueに交差 // ここでセグメント BOOLのseg_seg(ラインL1、L2行) { 戻り SGN(xmult (l1.s、l2.s、l2.e)* xmult(l1.e、l2.s、l2.e))<= 0 && SGN(xmult(l2.s、l1.s、l1.e)* xmult (l2.e、l1.s、l1.e))<= 0 ; } // 両者間の距離 の二重DIST(点A、点B) { 戻り SQRT((AB&)*(AB& )); } // 極角ソーティング; 100ポイント極角ソートする int型の POSを; // 極添字 点p [MAXN ]; INT スタック[MAXN]、トップ; BOOL CMP(点A、点B) { ダブル TMP = SGN((AP [POS])^(BP [POS])); // ソート反時計 IF( == TMP 0)リターン DIST(A、P [POS])< DIST(B、P [POS]); IF(TMP < 0)リターン falseに、 戻り trueに; } ボイドグラハム(int型N) { 点P0。 int型のk = 0 。 P0 = P [ 0 ]。 用(int型 i = 1 ; iが<N; iが++)// 找到最左下边的点 { 場合(p0.y> P [I] || .Y(SGN(p0.yp [I] .Y))= = 0 && P0.X> P [I] .X) { P0 = P [i]は、 kは = I。 } } スワップ(P [K]、P [ 0 ])。 ソート(P + 1、P + N、CMP)。 もし(nは==1 ) { トップ = 2 。 スタック[ 0 ] = 0 。 返します。 } であれば(N == 2 ) { トップ = 2 。 スタック[ 0 ] = 0 。 スタック[ 1 ] = 1 。 返します。 } スタックは[ 0 ] = 0 ;スタック[ 1 ] = 1 。 トップ = 2 。 以下のために(int型 I = 2、iは<N; iは++ ) { 一方(TOP> 1つの && SGN((P [スタック[トップ1 ] - P [スタック[トップ2 ])^(P [I] -p [スタック[トップ2 ]))<= 0 ) トップ - 。 [トップスタック ++] = I; } } int型のn; ブールチェック() { 場合(N < 6)を返す 偽。 場合(トップ< 2)を返す 偽。 にとって(int型 I = 0 ; iがトップ< 1 ; iが++ ) { int型 ANS = 0 。 用(INT J = 0 J ++; J <N ) であれば(P、xmult(P [J] [スタック[I]、P [スタック[I + 1 ]])== 0 ) ANS ++ 。 場合(ANS < 3 ) を返す 偽。 } を返す 真。 } int型のmain() { int型のT。 CIN>> トン; 一方、(t-- ) { CIN >> N。 以下のために(int型 i = 0 ; iがn <I ++は) CIN >> P [i]は.X >> Pを[I] .Y。 グラハム(N)// N和トップ都是指点的个数 場合(チェック()) COUT << " YES " << ENDL。 他の 裁判所未満 << " NO " << てendl; } }