3743 -- LL’s cake

  搞了好久都过不了,看了下题解是用PSLG来做的。POJ 2164 && LA 3218 Find the Border (Geometry, PSLG 平面直线图) - LyonLys - 博客园 这篇里面写过一下,就是把点都提取出来,然后模拟沿着边界移动,找到多边形并计算面积。

  而我的做法是直接模拟多边形切割,各种超时爆内存。先留着,看以后能不能用这个来过。

没过的代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <vector>
  7 #include <queue>
  8 
  9 using namespace std;
 10 
 11 const double EPS = 1e-4;
 12 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
 13 struct Point {
 14     double x, y;
 15     Point() {}
 16     Point(double x, double y) : x(x), y(y) {}
 17     Point operator + (Point a) { return Point(x + a.x, y + a.y);}
 18     Point operator - (Point a) { return Point(x - a.x, y - a.y);}
 19     Point operator * (double p) { return Point(x * p, y * p);}
 20     Point operator / (double p) { return Point(x / p, y / p);}
 21     bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && y < a.y;}
 22     bool operator == (Point a) const { return sgn(x - a.x) == 0 && sgn(y - a.y) == 0;}
 23 } ;
 24 
 25 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
 26 inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
 27 inline double veclen(Point x) { return sqrt(dot(x, x));}
 28 inline Point normal(Point x) { return Point(-x.y, x.x) / veclen(x);}
 29 inline Point vecunit(Point x) { return x / veclen(x);}
 30 
 31 struct Line {
 32     Point s, t;
 33     Line() {}
 34     Line(Point s, Point t) : s(s), t(t) {}
 35     Point vec() { return t - s;}
 36     Point point(double x) { return s + vec() * x;}
 37 } ;
 38 inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
 39 inline bool onseg(Point x, Point s, Point t) { return sgn(cross(s - x, t - x)) == 0 && sgn(dot(s - x, t - x)) < 0;}
 40 inline bool onseg(Point x, Line a) { return onseg(x, a.s, a.t);}
 41 
 42 struct Circle {
 43     Point c;
 44     double r;
 45     Circle() {}
 46     Circle(Point c, double r) : c(c), r(r) {}
 47     bool in(Point x) { return sgn(veclen(x - c) - r) <= 0;}
 48     Point point(double x) { return Point(c.x + cos(x) * r, c.y + sin(x) * r);}
 49 } ;
 50 const double R = 10.0;
 51 Circle cake = Circle(Point(0.0, 0.0), R);
 52 const double PI = acos(-1.0);
 53 template<class T> T sqr(T x) { return x * x;}
 54 inline double angle(Point x) { return atan2(x.y, x.x);}
 55 
 56 int clint(Line s, Point *sol) {
 57     Point nor = normal(s.vec()), ip = llint(s, Line(cake.c, cake.c + nor));
 58     double dis = veclen(cake.c - ip);
 59     if (sgn(dis - cake.r) >= 0) return 0;
 60     Point dxy = vecunit(s.vec()) * sqrt(sqr(cake.r) - sqr(dis));
 61     int ret = 0;
 62     sol[ret] = ip + dxy;
 63     if (onseg(sol[ret], s)) ret++;
 64     sol[ret] = ip - dxy;
 65     if (onseg(sol[ret], s)) ret++;
 66     return ret;
 67 }
 68 
 69 double getsec(Point a, Point b) {
 70     double a1 = angle(a - cake.c);
 71     double a2 = angle(b - cake.c);
 72     double da = fabs(a1 - a2);
 73     if (da > PI) da = PI * 2.0 - da;
 74     return sqr(cake.r) * da * sgn(cross(a - cake.c, b - cake.c)) / 2.0;
 75 }
 76 
 77 inline double gettri(Point a, Point b) { return cross(a - cake.c, b - cake.c) / 2.0;}
 78 //typedef vector<Point> VP;
 79 const int N = 111;
 80 struct VP {
 81     Point vex[N];
 82     int n;
 83     void clear() { n = 0;}
 84     void push_back(Point x) { vex[n++] = x;}
 85     void pop_back() { n--;}
 86     int size() { return n;}
 87 } ;
 88 
 89 double cpint(VP pt) {
 90     double ret = 0.0;
 91     int n = pt.size();
 92     Point tmp[2];
 93     pt.vex[n] = pt.vex[0];
 94     for (int i = 0; i < n; i++) {
 95         int ic = clint(Line(pt.vex[i], pt.vex[i + 1]), tmp);
 96         if (ic == 0) {
 97             if (!cake.in(pt.vex[i]) || !cake.in(pt.vex[i + 1])) ret += getsec(pt.vex[i], pt.vex[i + 1]);
 98             else ret += gettri(pt.vex[i], pt.vex[i + 1]);
 99         } else if (ic == 1) {
100             if (cake.in(pt.vex[i])) ret += gettri(pt.vex[i], tmp[0]), ret += getsec(tmp[0], pt.vex[i + 1]);
101             else ret += getsec(pt.vex[i], tmp[0]), ret += gettri(tmp[0], pt.vex[i + 1]);
102         } else {
103             if (pt.vex[i] < pt.vex[i + 1] ^ tmp[0] < tmp[1]) swap(tmp[0], tmp[1]);
104             ret += getsec(pt.vex[i], tmp[0]);
105             ret += gettri(tmp[0], tmp[1]);
106             ret += getsec(tmp[1], pt.vex[i + 1]);
107         }
108 //        cout << "~~ic " << ic << ' ' << ret << endl;
109     }
110     return fabs(ret);
111 }
112 
113 bool fixpoly(VP &poly) {
114     double sum = 0.0;
115     int n = poly.size();
116     poly.vex[n] = poly.vex[0];
117     for (int i = 0; i < n; i++) sum += cross(poly.vex[i], poly.vex[i + 1]);
118     if (sgn(sum) == 0) return false;
119     if (sgn(sum) < 0) reverse(poly.vex, poly.vex + n);
120     return true;
121 }
122 
123 void cutpoly(VP &poly, Line l, VP &ret) {
124     ret.clear();
125     int n = poly.size();
126 //    cout << n << endl;
127     poly.vex[n] = poly.vex[0];
128     for (int i = 0; i < n; i++) {
129         if (sgn(cross(l.vec(), poly.vex[i] - l.s)) >= 0) ret.push_back(poly.vex[i]);
130         if (sgn(cross(l.vec(), poly.vex[i] - poly.vex[i + 1]))) {
131             Point ip = llint(l, Line(poly.vex[i], poly.vex[i + 1]));
132 //            cout << "ip " << ip.x << ' ' << ip.y << endl;
133             if (onseg(ip, poly.vex[i], poly.vex[i + 1]) || poly.vex[i] == ip) ret.push_back(ip);
134         }
135     }
136 //    cout << "cp sz " << ret.size() << endl;
137 }
138 
139 const int M = 22222;
140 int q[1111111], qh, qt, nu;
141 VP rec[M];
142 queue<int> recycle;
143 
144 int getID() {
145     int ret;
146     if (nu >= M) {
147         if (recycle.empty()) { puts("shit!"); while (1) ;}
148         ret = recycle.front();
149         recycle.pop();
150     } else ret = nu++;
151     return ret;
152 }
153 
154 void retID(int x) { recycle.push(x);}
155 
156 int main() {
157 //    freopen("in", "r", stdin);
158 //    freopen("out", "w", stdout);
159     int T, n, tmp;
160     double x, y;
161     cin >> T;
162     while (T-- && cin >> n) {
163         while (!recycle.empty()) recycle.pop();
164         qh = qt = nu = 0;
165         tmp = getID();
166         rec[tmp].clear();
167         rec[tmp].push_back(Point(-R * 2.0, -R * 2.0));
168         rec[tmp].push_back(Point(R * 2.0, -R * 2.0));
169         rec[tmp].push_back(Point(R * 2.0, R * 2.0));
170         rec[tmp].push_back(Point(-R * 2.0, R * 2.0));
171         fixpoly(rec[tmp]);
172         q[qt++] = tmp;
173         for (int i = 0; i < n; i++) {
174             cin >> x >> y;
175             int sz = qt - qh;
176             Line t = Line(cake.point(x), cake.point(y));
177 //            cout << cake.point(x).x << '=' << cake.point(x).y << endl;
178 //            cout << cake.point(y).x << '~' << cake.point(y).y << endl;
179             for (int j = 0; j < sz; j++) {
180                 tmp = getID();
181 //                cout << "qh ?? " << qh << ' ' << q[qh] << ' ' << rec[q[qh]].size() << endl;
182                 cutpoly(rec[q[qh]], t, rec[tmp]);
183                 if (fixpoly(rec[tmp])) {
184 //                    cout << j << "~~1 " << rec[tmp].size() << endl;
185 //                    for (int k = 0; k < rec[tmp].size(); k++) cout << rec[tmp].vex[k].x << ' ' << rec[tmp].vex[k].y << endl;
186                     q[qt++] = tmp;
187                 }
188                 swap(t.s, t.t);
189                 tmp = getID();
190                 cutpoly(rec[q[qh]], t, rec[tmp]);
191                 if (fixpoly(rec[tmp])) {
192 //                    cout << j << "~~2 " << rec[tmp].size() << endl;
193 //                    for (int k = 0; k < rec[tmp].size(); k++) cout << rec[tmp].vex[k].x << ' ' << rec[tmp].vex[k].y << endl;
194                     q[qt++] = tmp;
195                 }
196                 retID(q[qh++]);
197             }
198 //            cout << "sz~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " << qt - qh << endl;
199         }
200         double mx = 0.0;
201         while (qh < qt) {
202             mx = max(mx, cpint(rec[q[qh++]]));
203 //            cout << ".. " << mx << endl;
204         }
205         printf("%.2f\n", mx);
206     }
207     return 0;
208 }
209 
210 /*
211 6
212 2
213 -3.140000 0.000000
214 -1.000000 1.000000
215 2
216 -3.141592 0.000000
217 -1.570796 1.570796
218 3
219 -3.000000 3.000000
220 -2.000000 2.000000
221 -1.000000 1.000000
222 4
223 -3.140000 0.000000
224 -1.000000 1.000000
225 -3.140000 -1.000000
226 1.000000 0.000000
227 6
228 -3.140000 0.000000
229 -1.000000 1.000000
230 -3.140000 -1.000000
231 1.000000 0.000000
232 -3.140000 -1.000000
233 1.000000 0.000000
234 6
235 -3.141592 0.000000
236 -1.570796 1.570796
237 -3.141592 -1.570796
238 0.000000 1.570796
239 -3.141592 1.570796
240 0.000000 -1.570796
241 */
View Code

相关文章:

  • 2021-12-16
  • 2021-09-28
  • 2022-12-23
  • 2022-12-23
  • 2021-08-18
  • 2021-05-20
  • 2021-11-17
猜你喜欢
  • 2021-05-26
  • 2021-09-19
  • 2022-12-23
  • 2022-01-02
  • 2018-03-04
  • 2022-12-23
相关资源
相似解决方案