Given a polygon shaped gallery, determine whether only one guard can observe the whole area.
This is merely a question of whether the polygon is convex or not. If there’s at least one reflex angle a
, a guard placed on an adjacent angle to a
will not be able to see the entire gallery because of a
.
Loop over perimeter and see if there’s any change in rotation direction.
#include <iostream> #include <algorithm> #include <complex> #include <vector> using namespace std; typedef long double gtype; const gtype pi = M_PI; typedef complex<gtype> point; #define x real() #define y imag() #define crs(a, b) ( (conj(a) * (b)).y ) bool polIsConvex(vector<point> & p) { int a[2] = { 0, 0 }, n = p.size() - 1; for (size_t i = 1; i < p.size(); ++i) { long double cross = crs(p[i % n] - p[i - 1], p[(i + 1) % n] - p[i - 1]); if (cross != 0) ++a[cross > 0]; } return !(a[0] && a[1]); } int main() { char answer[2][4] = { "Yes", "No" }; int n; while (cin >> n && n) { // polygons vector<point> p(n + 1); for (int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y; p[n] = p[0]; // is convex cout << answer[polIsConvex(p)] << endl; } return 0; }
Find the convex hull and compare both polygons.
#include <iostream> #include <algorithm> #include <complex> #include <vector> using namespace std; typedef long double gtype; const gtype pi = M_PI; typedef complex<gtype> point; #define x real() #define y imag() bool cmp_point(point const& p1, point const& p2) { return p1.x == p2.x ? (p1.y < p2.y) : (p1.x < p2.x); } #define crs(a, b) ( (conj(a) * (b)).y ) vector<point> mcH; void monotoneChain(vector<point> &ps) { vector<point> p(ps.begin(), ps.end() - 1); int n = p.size(), k = 0; mcH = vector<point>(2 * n); sort(p.begin(), p.end(), cmp_point); for (int i = 0; i < n; i++) { while (k >= 2 && crs(mcH[k - 1] - mcH[k - 2], p[i] - mcH[k - 2]) < 0) k--; mcH[k++] = p[i]; } for (int i = n - 2, t = k + 1; i >= 0; i--) { while (k >= t && crs(mcH[k - 1] - mcH[k - 2], p[i] - mcH[k - 2]) < 0) k--; mcH[k++] = p[i]; } mcH.resize(k); } int main() { char answer[2][4] = { "Yes", "No" }; int n; while (cin >> n && n) { // polygons vector<point> p(n + 1); for (int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y; p[n] = p[0]; // is convex monotoneChain(p); cout << answer[mcH.size() == n + 1] << endl; } return 0; }
Since is too small, there’s no much of a difference.