Description
Input
Output
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 8 const int MAXN = 1010; 9 const double EPS = 1e-8; 10 const double PI = acos(-1.0);//3.14159265358979323846 11 12 inline int sgn(double x) { 13 return (x > EPS) - (x < -EPS); 14 } 15 16 struct Point { 17 double x, y; 18 Point() {} 19 Point(double x, double y): x(x), y(y) {} 20 void read() { 21 scanf("%lf%lf", &x, &y); 22 } 23 bool operator == (const Point &rhs) const { 24 return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0; 25 } 26 bool operator < (const Point &rhs) const { 27 if(y != rhs.y) return y < rhs.y; 28 return x < rhs.x; 29 } 30 Point operator + (const Point &rhs) const { 31 return Point(x + rhs.x, y + rhs.y); 32 } 33 Point operator - (const Point &rhs) const { 34 return Point(x - rhs.x, y - rhs.y); 35 } 36 Point operator * (const int &b) const { 37 return Point(x * b, y * b); 38 } 39 Point operator / (const int &b) const { 40 return Point(x / b, y / b); 41 } 42 double length() const { 43 return sqrt(x * x + y * y); 44 } 45 Point unit() const { 46 return *this / length(); 47 } 48 }; 49 typedef Point Vector; 50 51 double dist(const Point &a, const Point &b) { 52 return (a - b).length(); 53 } 54 55 double cross(const Point &a, const Point &b) { 56 return a.x * b.y - a.y * b.x; 57 } 58 //ret >= 0 means turn left 59 double cross(const Point &sp, const Point &ed, const Point &op) { 60 return sgn(cross(sp - op, ed - op)); 61 } 62 63 double area(const Point& a, const Point &b, const Point &c) { 64 return fabs(cross(a - c, b - c)) / 2; 65 } 66 67 struct Seg { 68 Point st, ed; 69 Seg() {} 70 Seg(Point st, Point ed): st(st), ed(ed) {} 71 void read() { 72 st.read(); ed.read(); 73 } 74 }; 75 typedef Seg Line; 76 77 bool isOnSeg(const Seg &s, const Point &p) { 78 return (p == s.st || p == s.ed) || 79 (((p.x - s.st.x) * (p.x - s.ed.x) < 0 || 80 (p.y - s.st.y) * (p.y - s.ed.y) < 0) && 81 sgn(cross(s.ed, p, s.st) == 0)); 82 } 83 84 bool isIntersected(const Point &s1, const Point &e1, const Point &s2, const Point &e2) { 85 return (max(s1.x, e1.x) >= min(s2.x, e2.x)) && 86 (max(s2.x, e2.x) >= min(s1.x, e1.x)) && 87 (max(s1.y, e1.y) >= min(s2.y, e2.y)) && 88 (max(s2.y, e2.y) >= min(s1.y, e1.y)) && 89 (cross(s2, e1, s1) * cross(e1, e2, s1) >= 0) && 90 (cross(s1, e2, s2) * cross(e2, e1, s2) >= 0); 91 } 92 93 bool isIntersected(const Seg &a, const Seg &b) { 94 return isIntersected(a.st, a.ed, b.st, b.ed); 95 } 96 97 bool isParallel(const Seg &a, const Seg &b) { 98 return sgn(cross(a.ed - a.st, b.ed - b.st)) == 0; 99 } 100 101 //return Ax + By + C =0 's A, B, C 102 void Coefficient(const Line &L, double &A, double &B, double &C) { 103 A = L.ed.y - L.st.y; 104 B = L.st.x - L.ed.x; 105 C = L.ed.x * L.st.y - L.st.x * L.ed.y; 106 } 107 108 Point intersection(const Line &a, const Line &b) { 109 double A1, B1, C1; 110 double A2, B2, C2; 111 Coefficient(a, A1, B1, C1); 112 Coefficient(b, A2, B2, C2); 113 Point I; 114 I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1); 115 I.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1); 116 return I; 117 } 118 119 bool isEqual(const Line &a, const Line &b) { 120 double A1, B1, C1; 121 double A2, B2, C2; 122 Coefficient(a, A1, B1, C1); 123 Coefficient(b, A2, B2, C2); 124 return sgn(A1 * B2 - A2 * B1) == 0 && sgn(A1 * C2 - A2 * C1) == 0 && sgn(B1 * C2 - B2 * C1) == 0; 125 } 126 127 struct Poly { 128 int n; 129 Point p[MAXN];//p[n] = p[0] 130 void init(Point *pp, int nn) { 131 n = nn; 132 for(int i = 0; i < n; ++i) p[i] = pp[i]; 133 p[n] = p[0]; 134 } 135 double area() { 136 if(n < 3) return 0; 137 double s = p[0].y * (p[n - 1].x - p[1].x); 138 for(int i = 1; i < n; ++i) 139 s += p[i].y * (p[i - 1].x - p[i + 1].x); 140 return s / 2; 141 } 142 }; 143 144 void Graham_scan(Point *p, int n, int *stk, int &top) { 145 sort(p, p + n); 146 top = 1; 147 stk[0] = 0; stk[1] = 1; 148 for(int i = 2; i < n; ++i) { 149 while(top && cross(p[i], p[stk[top]], p[stk[top - 1]]) >= 0) --top; 150 stk[++top] = i; 151 } 152 int len = top; 153 stk[++top] = n - 2; 154 for(int i = n - 3; i >= 0; --i) { 155 while(top != len && cross(p[i], p[stk[top]], p[stk[top - 1]]) >= 0) --top; 156 stk[++top] = i; 157 } 158 } 159 160 /*******************************************************************************************/ 161 162 Point p[MAXN]; 163 Poly poly; 164 int stk[MAXN], top; 165 int n, T; 166 167 bool check() { 168 poly.n = top; 169 for(int i = 0; i < top; ++i) poly.p[i] = p[stk[i]]; 170 poly.p[poly.n] = poly.p[0]; 171 if(sgn(poly.area()) == 0) return false; 172 for(int i = 0; i < poly.n; ++i) { 173 bool flag = false; 174 for(int j = 0; j < n; ++j) { 175 if(p[j] == poly.p[i] || p[j] == poly.p[i + 1]) continue; 176 if(isOnSeg(Seg(poly.p[i], poly.p[i + 1]), p[j])) { 177 flag = true; 178 break; 179 } 180 } 181 if(!flag) return false; 182 } 183 return true; 184 } 185 186 int main() { 187 scanf("%d", &T); 188 while(T--) { 189 scanf("%d", &n); 190 for(int i = 0; i < n; ++i) p[i].read(); 191 Graham_scan(p, n, stk, top); 192 if(check()) puts("YES"); 193 else puts("NO"); 194 } 195 }