キーワード:極角は、単純なポリゴンの生成をソート
質問の意味:
非順序集合セット平面ポイントに、目標は、単純なポリゴンを構築することで、簡単なポリゴンポリゴン比べ制約は(被写体が特定の記述を有する)項ポリゴン無限の自家受粉に定義されています。
分析:
ポリゴンとしてシーケンス内の任意のポイント。単純なポリゴンの制約を満たす配列に対応する特定の元の配列に結果をソートコンパレータは、自己元のシーケンスと見ることができます。ここではそのユニバーサル配列ソートアルゴリズムによって適用することができ、望ましい結果を与えるために、コンパレータがある意味するかもしれません。
答えは、極角の一種である古典的なグラハムスキャンアルゴリズムの問題に対して、プリソートサブ標準凸包アルゴリズムです。極角は、共通の軸に基づく一種の古典的なアイデアを発注点の二次元セットの一種であるグラハムスキャンスキャンはポールのどの部分を直接扱うことができますが、単純なポリゴンとして、あるいは特殊なケースの無限大で小修理の後に見ることができます点の軸基づいてソート順序を処理します。この時点で、直感的な指導のいくつかの種類があります:シンプルなポリゴン構造的な問題は、グラハムスキャンマイクロレタッチプリソートすることによって解決することができます。
特別なマルチ共線点(点極)プロセス定義をソート極角を追加する必要があり、グラハム・スキャンは、スキャンを達成するために、遅延にマルチ同一直線上の点を扱うことができます。多重共線点が増加する直径の補足部分配列順序を電極として定義され、特別な場合は、隣接する共通電極線間隔の方向である配列を減速。
なぜインポッシブル?すべてのポイントが同じ行にあります。
コード:
#include <iostream>
#include <array>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
namespace cglib {
template <class Type = int>
struct Vec2{
Type x, y;
Vec2(){}
Vec2(Type _x, Type _y): x(_x), y(_y){}
bool operator < (const Vec2& rhs) {
return y == rhs.y ? x < rhs.x : y < rhs.y;
}
Vec2 operator - (const Vec2& rhs) const {
return Vec2(rhs.x - x, rhs.y - y);
}
double length2() const {
return x * x + y * y;
}
};
using vec2i = Vec2<int>;
template <class Type>
int to_left_test(const Type p, const Type q, const Type s) {
int x = _Area(p, q, s);
return x == 0 ? -1: x > 0;
}
template <class Type>
int _Area(const Type& p, const Type& q, const Type& s) {
return p.x * q.y - p.y * q.x +
q.x * s.y - q.y * s.x +
s.x * p.y - s.y * p.x;
}
bool graham_presort(std::vector<vec2i>& P, std::vector<int>& idx) {
std::swap(idx[0], idx[std::min_element(P.begin(), P.end())-P.begin()]);
bool is_same_line = true;
std::sort(idx.begin()+1, idx.end(), [&](const int& lhs, const int& rhs)->bool{
switch (to_left_test(P[idx[0]], P[lhs], P[rhs])) {
case -1:
return (P[lhs]-P[idx[0]]).length2() < (P[rhs]-P[idx[0]]).length2();
case 0:
is_same_line = false;
return false;
case 1:
is_same_line = false;
return true;
}
});
if(!is_same_line) {
for(int i = idx.size()-2; i > 0; i--) {
if(to_left_test(P[idx[0]], P[*idx.rbegin()], P[idx[i]]) == -1) continue;
std::reverse(idx.begin()+i+1, idx.end());
break;
}
}
return !is_same_line;
}
}
int main() {
using namespace cglib;
int T, N;
std::cin >> T;
for(int t = 0; t < T; t++) {
std::cin >> N;
std::vector<vec2i> P;
vec2i p;
for(int i = 0; i < N; i++) {
std::cin >> p.x >> p.y;
P.emplace_back(p);
}
std::vector<int> idx(P.size());
for(int i = 0; i < idx.size(); i++) idx[i] = i;
std::cout << "Case " << t+1 << ":" << std::endl;
if( !graham_presort(P, idx) ) {
std::cout << "Impossible\n";
}
else {
for(int i = 0; i < idx.size()-1; i++)
std::cout << idx[i] << ' ';
std::cout << *idx.rbegin() << std::endl;
}
}
}