給定平面上N個點,請計算出凸包上的頂點數。所謂的凸包,就是指一個包含所有點的最小凸多邊形。
所謂凸包上的頂點,指的是轉折處(邊上的點不算)。
$1\leq N\leq 10,000$
點的座標皆在int範圍
凸包裸題
用Andrew’s Monotone Chain來實作
複雜度$\mathcal{O}(NlogN)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<bits/stdc++.h> using namespace std;
long long cross(pair<long long,long long> &a, pair<long long,long long> &b, pair<long long,long long> &c) { return (b.first-a.first) * (c.second - a.second) - (b.second - a.second) * (c.first - a.first); }
signed main() { ios::sync_with_stdio(0); cin.tie(0);
int n; cin >> n; vector<pair<long long,long long>> arr(n), dn, up; for(int i = 0; i < n; i++) cin >> arr[i].first >> arr[i].second; sort(arr.begin(), arr.end());
for(int i = 0; i < n; i++) { while(dn.size() >= 2 && cross(dn[dn.size()-2], dn.back(), arr[i]) <= 0) dn.pop_back(); while(up.size() >= 2 && cross(up[up.size()-2], up.back(), arr[i]) >= 0) up.pop_back(); dn.push_back(arr[i]); up.push_back(arr[i]); }
for(int i = int(up.size())-2; i > 0; i--) dn.push_back(up[i]); cout << dn.size();
return 0; }
|