Skip to content
Snippets Groups Projects
Commit 85adab67 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

Add convex hull

parent e9797f72
No related branches found
No related tags found
No related merge requests found
#include <bits/stdc++.h>
#define MAX 0
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define sz size()
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef pair<double,double> dd;
double cross(dd a, dd b, dd c) {
return (b.fi - a.fi) * (c.se - a.se) - (b.se - a.se) * (c.fi - a.fi);
}
int convex_hull(vector<dd> &v) {
int k = 0;
vector<int> ans(v.sz * 2);
sort(v.begin(), v.end(), [](const dd &a, const dd &b) -> bool {
return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi);
});
for (int i = 0; i < v.sz; ++i) {
while (k >= 2 && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--;
ans[k++] = i;
}
for (int i = v.sz - 2, t = k + 1; i >= 0; --i) {
while (k >= t && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--;
ans[k++] = i;
}
ans.resize(k);
sort(rall(ans));
ans.erase(unique(all(ans)), ans.end());
for (auto i : ans)
v.erase(v.begin() + i);
return k - 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
while (cin >> n && n) {
vector<dd> v;
double x, y;
for (int i = 0; i < n; ++i) {
cin >> x >> y;
v.pb(dd(x, y));
}
int ans = 0;
while (v.sz) {
convex_hull(v);
ans++;
}
if (ans % 2) cout << "Take this onion to the lab!\n";
else cout << "Do not take this onion to the lab!\n";
}
return 0;
}
/**
* Convex Hull
*
* Complexity (Time): O(n log n)
* Complexity (Space): O(n)
*/
typedef pair<double,double> dd;
// The three points are a counter-clockwise turn if cross > 0, clockwise if
// cross < 0, and collinear if cross = 0
double cross(dd a, dd b, dd c) {
return (b.fi - a.fi) * (c.se - a.se) - (b.se - a.se) * (c.fi - a.fi);
}
// Find, among v, the points that form a convex hull
int convex_hull(const vector<dd> &v) {
int k = 0;
vector<int> ans(v.sz * 2);
// Sort points
sort(v.begin(), v.end(), [](const dd &a, const dd &b) -> bool {
return (a.fi == b.fi) ? (a.se < b.se) : (a.fi < b.fi);
});
// Uppermost part of convex hull
for (int i = 0; i < v.sz; ++i) {
while (k >= 2 && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--;
ans[k++] = i;
}
// Lowermost part of convex hull
for (int i = v.sz - 2, t = k + 1; i >= 0; --i) {
while (k >= t && cross(v[ans[k - 2]], v[ans[k - 1]], v[i]) < 0) k--;
ans[k++] = i;
}
// The ans vector contains the indices (relative to the sorted vector!) of
// the points belonging to the convex hull
ans.resize(k);
// Remove duplicates
sort(all(ans));
ans.erase(unique(all(ans)), ans.end());
// Returns amount of point in the convex hull
return k - 1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment