四:半平面交

Rotating Scoreboard

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool cmp_Half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e3 + 10;Line que[N];bool Half_lane_intersection(vector<Line> &a) {sort(a.begin(), a.end(), cmp_Half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;if (tail - head < 3) return false;return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T;scanf("%d", &T);while(T--) {int n;scanf("%d", &n);vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}if(Half_lane_intersection(a)) puts("YES");else puts("NO");}return 0;
}

How I Mathematician Wonder What You Are!

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool cmp_Half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e3 + 10;Line que[N];bool Half_lane_intersection(vector<Line> &a) {sort(a.begin(), a.end(), cmp_Half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;if (tail - head < 3) return false;return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int n;while(scanf("%d", &n) && n) {vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}if(Half_lane_intersection(a)) puts("1");else puts("0");}return 0;
}

Video Surveillance

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool cmp_Half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e3 + 10;Line que[N];bool Half_lane_intersection(vector<Line> &a) {sort(a.begin(), a.end(), cmp_Half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;if (tail - head < 3) return false;return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int n, cas = 1;while(scanf("%d", &n) && n) {vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}printf("Floor #%d\n", cas++);if(!Half_lane_intersection(a)) puts("Surveillance is impossible.");else puts("Surveillance is possible.");puts("");}return 0;
}

Art Gallery

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool Cmp_half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e4 + 10;Line que[N];double Half_lane_intersection(vector<Line> &a) {sort(a.begin(), a.end(), Cmp_half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;n = tail - head;if(n < 3) return 0;vector<Point> ans;for(int i = head; i < tail; i++) {ans.push_back(Intersect_point(que[i], que[(i + 1) % n + head]));}return Area(ans, ans.size());// if (tail - head < 3) return false;// return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T, n;scanf("%d", &T);while(T--) {scanf("%d", &n);vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}printf("%.2f\n", Half_lane_intersection(a));}return 0;
}

Most Distant Point from the Sea

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool Cmp_half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e4 + 10;Line que[N];bool Half_lane_intersection(vector<Line> a, double x) {sort(a.begin(), a.end(), Cmp_half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n; i++) {Vector dir = a[i].ed - a[i].st;dir = dir.Rotate(pi / 2);double mod = dir.mod();dir.x /= mod, dir.y /= mod;a[i].st = a[i].st + (dir << x);a[i].ed = a[i].ed + (dir << x);}for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;// n = tail - head;// if(n < 3) return 0;// vector<Point> ans;// for(int i = head; i < tail; i++) {//     ans.push_back(Intersect_point(que[i], que[(i + 1) % n + head]));// }// return Area(ans, ans.size());if (tail - head < 3) return false;return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T, n;// scanf("%d", &T);while(scanf("%d", &n) && n) {// scanf("%d", &n);vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}double l = 0, r = 10000;for(int i = 1; i <= 300; i++) {double mid = (l + r) / 2;if(Half_lane_intersection(a, mid)) l = mid;else r = mid;}printf("%.6f\n", l);}return 0;
}

Feng Shui (待调)

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;const double pi = acos(-1.0);
const double eps = 1e-5;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}// ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool Cmp_half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 1e4 + 10;Line que[N];void Half_lane_intersection(vector<Line> a, double x) {sort(a.begin(), a.end(), Cmp_half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n; i++) {Vector dir = a[i].ed - a[i].st;dir = dir.Rotate(pi / 2);double mod = dir.mod();dir.x /= mod, dir.y /= mod;a[i].st = a[i].st + (dir << x);a[i].ed = a[i].ed + (dir << x);}for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;n = tail - head;// if(n < 3) return 0;vector<Point> ans;for(int i = head; i < tail; i++) {ans.push_back(Intersect_point(que[i], que[(i + 1) % n + head]));}double dis = -1;int fi = 0, se = 0;n = ans.size();for(int i = 0; i < n; i++) {for(int j = i + 1; j < n; j++) {double now = Dis_pp(ans[i], ans[j]);if(Sgn(now - dis) > 0) {fi = i, se = j;dis = now;}}}if(fabs(ans[fi].x) < eps) ans[fi].x = 0;if(fabs(ans[fi].y) < eps) ans[fi].y = 0;if(fabs(ans[se].x) < eps) ans[se].x = 0;if(fabs(ans[se].y) < eps) ans[se].y = 0;printf("%.4f %.4f %.4f %.4f\n", ans[fi].x, ans[fi].y, ans[se].x, ans[se].y);// return Area(ans, ans.size());// if (tail - head < 3) return false;// return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T, n;double r;// scanf("%d", &T);while(scanf("%d %lf", &n, &r) != EOF) {// scanf("%d", &n);vector<Point> res;for(int i = 0; i < n; i++) {Point ans;ans.read();res.push_back(ans);}double area = Area(res, n);vector<Line> a;if(area > 0) {for(int i = 0; i < n; i++) {a.push_back(Line(res[i], res[(i + 1) % n]));}}else {for(int i = n - 1; i >= 0; i--) {a.push_back(Line(res[(i + 1) % n], res[i]));}}Half_lane_intersection(a, r);}return 0;
}

Triathlon

Hotter Colder

Uyuw’s Concert(待修正)

/*Author : lifehappy
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std;#define double long doubleconst double pi = acos(-1.0);
const double eps = 1e-10;
const double inf = 1e100;int Sgn(double x) {return x < -eps ? -1 : x > eps;
}struct Vector {double x, y;bool operator < (Vector &a) const {return x < a.x;}void print() {printf("%f %f\n", x, y);}void read() {scanf("%lf %lf", &x, &y);}Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}double mod() {return sqrt(x * x + y * y);}double mod2() {return x * x + y * y;}Vector operator + (const Vector &a) {return Vector(x + a.x, y + a.y);}Vector operator - (const Vector &a) {return Vector(x - a.x, y - a.y);}double operator * (const Vector &a) {return x * a.x + y * a.y;}double operator ^ (const Vector &a) {return x * a.y - y * a.x;}Vector Rotate(double angle) {return Vector(x * cos(angle) - y * sin(angle), x * sin(angle) + y * cos(angle));}Vector operator << (const double &a) {return Vector(x * a, y * a);}Vector operator >> (const double &a) {return Vector(x / a, y / a);}bool operator == (const Vector & a) {return (Sgn(x - a.x) == 0) && (Sgn(y - a.y) == 0);}
};typedef Vector Point;double Dis_pp(Point a, Point b) {return sqrt((a - b) * (a - b));
}double Angle(Vector a, Vector b) {//[0, 2pi)double ans = atan2(a ^ b, a * b);return ans < 0 ? ans + 2 * pi : ans;// return atane(a ^ b, a * b);
}double To_lefttest(Point a, Point b, Point c) {return (b - a) ^(c - a);
}int Toleft_test(Point a, Point b, Point c) {return Sgn((b - a) ^ (c - a));
}struct Line {Point st, ed;Line(Point _st = Point(0, 0), Point _ed = Point(0, 0)) : st(_st), ed(_ed) {}bool operator < (const Line &t) {return st.x < t.st.x;}void read() {scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);}
};bool Parallel(Line a, Line b) {return Sgn((a.st - a.ed) ^ (b.st - b.ed)) == 0;
}bool Is_cross(Line a, Line b) {return Toleft_test(a.st, a.ed, b.st) * Toleft_test(a.st, a.ed, b.ed) <= 0 && Toleft_test(b.st, b.ed, a.st) * Toleft_test(b.st, b.ed, a.ed) <= 0;
}Point Cross_point(Line a, Line b) {if(!Is_cross(a, b)) {return Point(inf, inf);}else {double a1 = fabs(To_lefttest(a.st, a.ed, b.st)), a2 = fabs(To_lefttest(a.st, a.ed, b.ed));return ((b.st << a2) + (b.ed << a1)) >> (a1 + a2);}
}Point Intersect_point(Line a, Line b) {double a1 = a.st.y - a.ed.y, b1 = a.ed.x - a.st.x, c1 = a.st.x * a.ed.y - a.ed.x * a.st.y;double a2 = b.st.y - b.ed.y, b2 = b.ed.x - b.st.x, c2 = b.st.x * b.ed.y - b.ed.x * b.st.y;return Point((c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2), (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1));
}Point Shadow(Line a, Point b) {Point dir = a.ed - a.st;return a.st + (dir << (((b - a.st) * dir) / dir.mod2()));
}Point Reflect(Line a, Point b) {return (Shadow(a, b) << 2) - b;
}bool inmid(double a, double b, double x) {if(a > b) swap(a, b);return Sgn(x - a) >= 0 && Sgn(b - x) >= 0;
}bool Point_in_line(Line a, Point b) {if(Toleft_test(a.st, a.ed, b) != 0) return false;return inmid(a.st.x, a.ed.x, b.x) && inmid(a.st.y, a.ed.y, b.y);
}double Dis_lp(Line a, Point b) {Point h = Shadow(a, b);if(Point_in_line(a, h)) {return Dis_pp(h, b);}return min(Dis_pp(a.st, b), Dis_pp(a.ed, b));
}// double Dis_ll(Line a, Line b) {//     if(Is_cross(a, b)) return 0;
//     return min({Dis_lp(a, b.st), Dis_lp(a, b.ed), Dis_lp(b, a.st), Dis_lp(b, a.ed)});
// }double Area(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += p[i] ^ p[(i + 1) % n];}return 0.5 * ans;
}double Len(vector<Point> p, int n) {double ans = 0;for(int i = 0; i < n; i++) {ans += Dis_pp(p[i], p[(i + 1) % n]);}return ans;
}bool Is_convex(Point *a, int n) {bool flag[3] = {0, 0, 0};for(int i = 0; i < n; i++) {flag[Sgn(To_lefttest(a[i], a[(i + 1) % n], a[(i + 2) % n])) + 1] = true;if(flag[0] && flag[2]) return false;}return true;
}Point p0;bool cmp_graham(Point a, Point b) {int flag = Toleft_test(p0, a, b);return flag == 0 ? Dis_pp(p0, a) < Dis_pp(p0, b) : flag > 0;
}vector<Point> Graham(vector<Point> &a, int n) {p0 = a[0];for(int i = 0; i < n; i++) {if(a[i].y < p0.y || (a[i].y == p0.y && a[i].x < p0.x)) {p0 = a[i];}}vector<Point> ans;sort(a.begin(), a.end(), cmp_graham);if(n == 1) {ans.push_back(a[0]);return ans;}if(n == 2) {ans.push_back(a[0]);ans.push_back(a[1]);return ans;}ans.push_back(a[0]);ans.push_back(a[1]);int sz = 2;for(int i = 2; i < n; i++) {while(sz > 1 && To_lefttest(ans[sz - 2], ans[sz - 1], a[i]) <= 0) {ans.pop_back();sz--;}ans.push_back(a[i]);sz++;}return ans;
}bool cmp_andrew(Point a, Point b) {if(Sgn(a.x - b.x) == 0)    return a.y < b.y;return a.x < b.x;
}vector<Point> Andrew(vector<Point> &a, int n) {sort(a.begin(), a.end(), cmp_andrew);int p1 = 0, p2;vector<Point> ans;for(int i = 0; i < n; i++) {while(p1 > 1 && Toleft_test(ans[p1 - 2], ans[p1 - 1], a[i]) <= 0)   ans.pop_back(), p1--;ans.push_back(a[i]), p1++;}p2 = p1;for(int i = n - 2; i>= 0; i--) {while(p2 > p1 && Toleft_test(ans[p2 - 2], ans[p2 - 1], a[i]) <= 0)  ans.pop_back(), p2--;ans.push_back(a[i]), p2++;}ans.pop_back();return ans;
}double Get_angle(Line a) {return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x);
}bool Cmp_half_lane_intersection(Line a, Line b) {Vector va = a.ed - a.st, vb = b.ed - b.st;double A =  Get_angle(va), B = Get_angle(vb);if (Sgn(A - B) == 0) return Sgn(((va) ^ (b.ed - a.st))) != -1;return Sgn(A - B) == -1;
}bool On_right(Line a, Line b, Line c) {Point o = Intersect_point(b, c);if (Sgn((a.ed - a.st) ^ (o - a.st)) < 0) return true;return false;
}const int N = 2e4 + 10;Line que[N];// Line que[2];double Half_lane_intersection(vector<Line> &a) {sort(a.begin(), a.end(), Cmp_half_lane_intersection);int head = 0, tail = 0, cnt = 0, n = a.size();for(int i = 0; i < n - 1; i++) {if(Sgn(Get_angle(a[i]) - Get_angle(a[i + 1])) == 0) continue;a[cnt++] = a[i];}a[cnt++] = a[n - 1];for(int i = 0; i < cnt; i++) {while(tail - head > 1 && On_right(a[i], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(a[i], que[head], que[head + 1])) head++;que[tail++] = a[i];}while(tail - head > 1 && On_right(que[head], que[tail - 1], que[tail - 2])) tail--;while(tail - head > 1 && On_right(que[tail - 1], que[head], que[head + 1])) head++;n = tail - head;if(n < 3) return 0;vector<Point> ans;for(int i = head; i < tail; i++) {ans.push_back(Intersect_point(que[i], que[(i + 1) % n + head]));}return Area(ans, ans.size());// if (tail - head < 3) return false;// return true;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int n;while(scanf("%d", &n) != EOF) {vector<Line> ans;for(int i = 1; i <= n; i++) {Line temp;temp.read();ans.push_back(temp);}ans.push_back(Line(Point(0, 0), Point(10000, 0)));ans.push_back(Line(Point(10000, 0), Point(10000, 10000)));ans.push_back(Line(Point(10000, 10000), Point(0, 10000)));ans.push_back(Line(Point(0, 1000), Point(0, 0)));printf("%.1lf\n", Half_lane_intersection(ans));}return 0;
}

半平面交练习(计算几何)相关推荐

  1. 模板:半平面交(计算几何)

    所谓半平面交,就是和"半平先生"当面交谈.顾名思义,这是一个源于日本的算法. (逃) 前言 感觉应用很灵活的一个算法,一切有两个变量的线性规划问题都可以转化为半平面交. 有时可能要 ...

  2. P4196-[CQOI2006]凸多边形/[模板]半平面交【计算几何】

    正题 题目链接:https://www.luogu.com.cn/problem/P4196 题目大意 给出nnn个凸多边形,求它们交的面积. 解题思路 就是把凸多边形上每条边作为一个半平面限制然后求 ...

  3. [模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

    一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson Simpson's Rule: \[ \int ^b_a f(x)dx\approx ...

  4. UVA1396 Most Distant Point from the Sea(AM - ICPC - Tokyo - 2007)(计算几何,半平面交 + 二分答案)

    整理的算法模板合集: ACM模板 题目传送门 见<训练指南>P279 很明显就是一个二分答案,它问的是最远的点,直接枚举因为这里都是double类型的数所以有无限个点,我们可以直接二分. ...

  5. 【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 959  Solved: 489 [Submit][Statu ...

  6. [JZOJ6093]【GDOI2019模拟2019.3.30】星辰大海【计算几何】【半平面交】

    Description 给出平面上n个点,其中1号点是可以移动的,但是移动的范围不能改变任意三个点所成的角的状态([0,π),[π,π],(π,2π][0,\pi),[\pi,\pi],(\pi,2\ ...

  7. LA 2218 (半平面交) Triathlon

    题意: 有n个选手,铁人三项有连续的三段,对于每段场地选手i分别以vi, ui 和 wi匀速通过. 对于每个选手,问能否通过调整每种赛道的长度使得他成为冠军(不能并列). 分析: 粗一看,这不像一道计 ...

  8. [jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)

    题目链接: https://jzoj.net/senior/#contest/show/2686/2 题目: 题解: 说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识 ...

  9. 【JZOJ3622】【BOI2011】2circles (半平面交+旋转卡壳)

    Problem 我们将会研究一个有N 个顶点的凸多边形.我们希望找到一个最大的半径R,使得两个半径为R 的圆能完全地放置在给出的多边形内,并没有重叠. Input 输入的第一行包含一个整数N.接下来N ...

最新文章

  1. 截取前四位字符串_Python的字符串切片
  2. ps2改usb接口_简单易懂,改装任意手柄为Type-C接口的方法
  3. 域名带后缀_[Python 爬虫]获取顶级域名及对应的 WHOIS Server 及 whoisservers.txt 下载...
  4. 自学Python:截取屏幕画面
  5. block介绍(四)揭开神秘面纱(下)
  6. DeepMind深度学习高级课程,视频已全部放出
  7. poj3262(Protecting the Flowers)贪心
  8. TelerikUI_RadGrid_Filter 自定义方法
  9. unity描边发光shader_Unity Shader 边缘高亮、描边
  10. 用计算机模拟宇宙,科学家尝试利用计算机模拟整个宇宙的演化
  11. 阿里系盒子英菲克i6八核 科学使用 笔记 (2015年12月26日成功)
  12. 嵌入式C语言(入门必看)
  13. Docker进阶学习(容器数据卷、安装Mysql、DockerFile )
  14. 利用接口检查日期是否为法定节假日
  15. Hadoop十年解读与发展预测
  16. 炒币风潮又起,区块链不该这么玩
  17. es数据更新时间_京东到家订单中心系统mysql到es的转化之路
  18. 成都盛铭轩:商品标题怎么写
  19. html常用标签梳理
  20. Android字母排序列表效果与开发实现

热门文章

  1. “爱因斯坦兄弟”事件轰动纽约时报!双胞胎乱写博士论文,整容后越黑越红,竟然名利双收..........
  2. C语言计算一个数的平方根立方根,怎样快速计算出一个数的平方根立方根?
  3. php json.parse,JSON.parse()与JSON.stringify()和eval()使用方法详解
  4. dubbo优势_Dubbo 迈出云原生重要一步 应用级服务发现解析
  5. 爱思助手短信备份到安卓_爱思助手肿么将短信导入iphone
  6. kafka 怎么样连接图形化界面_图形化编程有多简单,点亮LED不到一分钟
  7. myclipes 配置php,myclipse使用技巧
  8. columnproperty server sql_获取SQL Server表字段的各种属性
  9. win8计算机安全模式,WIN8如何设置按F8进入安全模式
  10. mysqlbinlog工具_mysqlbinlog命令详解 Part 1-实验环境准备