杭电oj初体验之 Code
PLA算法:
https://blog.csdn.net/red_stone1/article/details/70866527
The problem:
Analysis:
题目链接可见:https://vjudge.net/contest/313395#problem/M
Reference codes:
1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 const int N = 105; 8 9 int n; 10 11 int sgn(long long x) { 12 return (x > 0) - (x < 0); 13 } 14 15 struct P { 16 long long d[3]; 17 long long& operator[](int x) { 18 return d[x]; 19 } 20 P () {} 21 P (long long a, long long b, long long c) { 22 d[0] = a; d[1] = b; d[2] = c; 23 } 24 }; 25 26 struct node { 27 P x; 28 int y; 29 } p[N]; 30 31 P operator+(P a, P b) { 32 P c; 33 for (int i = 0; i < 3; i++) 34 c[i] = a[i] + b[i]; 35 return c; 36 } 37 38 P operator-(P a, P b) { 39 P c; 40 for (int i = 0; i < 3; i++) 41 c[i] = a[i] - b[i]; 42 return c; 43 } 44 45 P operator*(int a, P b) { 46 P c; 47 for (int i = 0; i < 3; i++) 48 c[i] = a * b[i]; 49 return c; 50 } 51 52 bool operator<(P a, P b) { 53 return a[1] < b[1] || (a[1] == b[1] && a[2] < b[2]); 54 } 55 56 long long operator*(P a, P b) { 57 return a[1] * b[2] - a[2] * b[1]; 58 } 59 60 long long operator^(P a, P b) { 61 return a[1] * b[1] + a[2] * b[2]; 62 } 63 64 long long det(P a, P b, P c) { 65 return (b - a) * (c - a); 66 } 67 68 struct L { 69 P a, b; 70 L () {} 71 L (P x, P y) { 72 a = x; b = y; 73 } 74 }; 75 76 bool onSeg(P p, L s) { 77 return sgn(det(p, s.a, s.b)) == 0 && sgn((s.a - p) ^ (s.b - p)) <= 0; 78 } 79 80 vector<P> convex(vector<P> p) { 81 vector<P> ans, S; 82 for (int i = 0; i < p.size(); i++) { 83 while (S.size() >= 2 84 && sgn(det(S[S.size() - 2], S.back(), p[i])) <= 0) 85 S.pop_back(); 86 S.push_back(p[i]); 87 } 88 ans = S; 89 S.clear(); 90 for (int i = (int)p.size() - 1; i >= 0; i--) { 91 while (S.size() >= 2 92 && sgn(det(S[S.size() - 2], S.back(), p[i])) <= 0) 93 S.pop_back(); 94 S.push_back(p[i]); 95 } 96 for (int i = 1; i + 1 < S.size(); i++) 97 ans.push_back(S[i]); 98 return ans; 99 } 100 101 bool PointInPolygon(P p, vector<P> poly) { 102 int cnt = 0; 103 for (int i = 0; i < poly.size(); i++) { 104 if (onSeg(p, L(poly[i], poly[(i + 1) % poly.size()]))) return true; 105 int k = sgn(det(poly[i], poly[(i + 1) % poly.size()], p)); 106 int d1 = sgn(poly[i][2] - p[2]); 107 int d2 = sgn(poly[(i + 1) % poly.size()][2] - p[2]); 108 if (k > 0 && d1 <= 0 && d2 > 0) cnt++; 109 if (k < 0 && d2 <= 0 && d1 > 0) cnt--; 110 } 111 if (cnt != 0) return true; 112 return false; 113 } 114 115 bool SegmentIntersection(L l1, L l2) { 116 long long c1 = det(l1.a, l1.b, l2.a), c2 = det(l1.a, l1.b, l2.b); 117 long long c3 = det(l2.a, l2.b, l1.a), c4 = det(l2.a, l2.b, l1.b); 118 if (sgn(c1) * sgn(c2) < 0 && sgn(c3) * sgn(c4) < 0) return true; 119 if (sgn(c1) == 0 && onSeg(l2.a, l1)) return true; 120 if (sgn(c2) == 0 && onSeg(l2.b, l1)) return true; 121 if (sgn(c3) == 0 && onSeg(l1.a, l2)) return true; 122 if (sgn(c4) == 0 && onSeg(l1.b, l2)) return true; 123 return false; 124 } 125 126 bool ConvexHullDivide(vector<P> p1, vector<P> p2) { 127 for (int i = 0; i < p1.size(); i++) 128 if (PointInPolygon(p1[i], p2)) 129 return false; 130 for (int i = 0; i < p2.size(); i++) 131 if (PointInPolygon(p2[i], p1)) 132 return false; 133 for (int i = 0; i < p1.size(); i++) 134 for (int j = 0; j < p2.size(); j++) 135 if (SegmentIntersection(L(p1[i], p1[(i + 1) % p1.size()]), L(p2[j], p2[(j + 1) % p2.size()]))) 136 return false; 137 return true; 138 } 139 140 bool check() { 141 vector<P> p1, p2; 142 for (int i = 1; i <= n; i++) { 143 if (p[i].y == 1) 144 p1.push_back(p[i].x); 145 else 146 p2.push_back(p[i].x); 147 } 148 vector<P> c1, c2; 149 c1 = convex(p1); 150 c2 = convex(p2); 151 if (ConvexHullDivide(c1, c2)) return true; 152 return false; 153 } 154 155 int f(P w, P x) { 156 long long sum = 0; 157 for (int i = 0; i < 3; i++) 158 sum += w[i] * x[i]; 159 return sgn(sum); 160 } 161 162 void PLA() { 163 P w = P(0, 0, 0); 164 int i = 1, cnt = 0; 165 long long cc = 0; 166 while (true) { 167 cc++; 168 if (f(w, p[i].x) != p[i].y) { 169 w = w + p[i].y * p[i].x; 170 cnt = 0; 171 } 172 else { 173 if (++cnt == n) break; 174 } 175 i = i + 1; 176 if (i > n) i -= n; 177 } 178 cout << cc << endl; 179 } 180 181 int main() { 182 int testcase; 183 cin >> testcase; 184 while (testcase--) { 185 cin >> n; 186 for (int i = 1; i <= n; i++) { 187 cin >> p[i].x[1] >> p[i].x[2] >> p[i].y; 188 p[i].x[0] = 1; 189 } 190 if (!check()) 191 puts("Infinite loop!"); 192 else { 193 puts("Successful!"); 194 } 195 } 196 return 0; 197 }