結果
問題 |
No.3154 convex polygon judge
|
ユーザー |
![]() |
提出日時 | 2025-05-20 21:54:23 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 73 ms / 2,000 ms |
コード長 | 2,450 bytes |
コンパイル時間 | 3,629 ms |
コンパイル使用メモリ | 283,120 KB |
実行使用メモリ | 13,656 KB |
最終ジャッジ日時 | 2025-05-20 21:54:29 |
合計ジャッジ時間 | 5,357 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 44 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; using Point = pair<ll, ll>; // return cross product of (b - a) x (c - a) ll cross(const Point &a, const Point &b, const Point &c) { return (b.first - a.first) * (c.second - a.second) - (b.second - a.second) * (c.first - a.first); } vector<Point> convex_hull(vector<Point> pts) { int n = pts.size(); if (n < 3) return pts; // 1) find pivot: smallest x (and then y) point int pivot = 0; for (int i = 1; i < n; i++) { if (pts[i].first < pts[pivot].first || (pts[i].first == pts[pivot].first && pts[i].second < pts[pivot].second)) pivot = i; } swap(pts[0], pts[pivot]); Point P0 = pts[0]; // 2) sort by polar angle around P0, tie-break by distance sort(pts.begin() + 1, pts.end(), [&](const Point &a, const Point &b) { ll c = cross(P0, a, b); if (c != 0) return c > 0; // if collinear, put closer point first ll da = (a.first - P0.first)*(a.first - P0.first) + (a.second - P0.second)*(a.second - P0.second); ll db = (b.first - P0.first)*(b.first - P0.first) + (b.second - P0.second)*(b.second - P0.second); return da < db; }); // 3) Graham scan vector<Point> hull; hull.push_back(pts[0]); hull.push_back(pts[1]); for (int i = 2; i < n; i++) { while (hull.size() >= 2 && cross(hull[hull.size()-2], hull[hull.size()-1], pts[i]) <= 0) { // remove non-left turn (<=0 removes collinear as well) hull.pop_back(); } hull.push_back(pts[i]); } return hull; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<Point> pts(N); for (int i = 0; i < N; i++) { cin >> pts[i].first >> pts[i].second; } // compute convex hull vector<Point> hull = convex_hull(pts); // if hull does not include all points, or N<3 if ((int)hull.size() != N) { cout << "No\n"; return 0; } // check no three consecutive points are collinear // wrap around: treat hull as circular for (int i = 0; i < N; i++) { Point a = hull[i]; Point b = hull[(i+1)%N]; Point c = hull[(i+2)%N]; if (cross(a, b, c) == 0) { cout << "No\n"; return 0; } } cout << "Yes\n"; return 0; }