3743 -- LL’s cake

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

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

没过的代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue> using namespace std; const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
Point operator + (Point a) { return Point(x + a.x, y + a.y);}
Point operator - (Point a) { return Point(x - a.x, y - a.y);}
Point operator * (double p) { return Point(x * p, y * p);}
Point operator / (double p) { return Point(x / p, y / p);}
bool operator < (Point a) const { return sgn(x - a.x) < || sgn(x - a.x) == && y < a.y;}
bool operator == (Point a) const { return sgn(x - a.x) == && sgn(y - a.y) == ;}
} ; inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
inline double veclen(Point x) { return sqrt(dot(x, x));}
inline Point normal(Point x) { return Point(-x.y, x.x) / veclen(x);}
inline Point vecunit(Point x) { return x / veclen(x);} struct Line {
Point s, t;
Line() {}
Line(Point s, Point t) : s(s), t(t) {}
Point vec() { return t - s;}
Point point(double x) { return s + vec() * x;}
} ;
inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
inline bool onseg(Point x, Point s, Point t) { return sgn(cross(s - x, t - x)) == && sgn(dot(s - x, t - x)) < ;}
inline bool onseg(Point x, Line a) { return onseg(x, a.s, a.t);} struct Circle {
Point c;
double r;
Circle() {}
Circle(Point c, double r) : c(c), r(r) {}
bool in(Point x) { return sgn(veclen(x - c) - r) <= ;}
Point point(double x) { return Point(c.x + cos(x) * r, c.y + sin(x) * r);}
} ;
const double R = 10.0;
Circle cake = Circle(Point(0.0, 0.0), R);
const double PI = acos(-1.0);
template<class T> T sqr(T x) { return x * x;}
inline double angle(Point x) { return atan2(x.y, x.x);} int clint(Line s, Point *sol) {
Point nor = normal(s.vec()), ip = llint(s, Line(cake.c, cake.c + nor));
double dis = veclen(cake.c - ip);
if (sgn(dis - cake.r) >= ) return ;
Point dxy = vecunit(s.vec()) * sqrt(sqr(cake.r) - sqr(dis));
int ret = ;
sol[ret] = ip + dxy;
if (onseg(sol[ret], s)) ret++;
sol[ret] = ip - dxy;
if (onseg(sol[ret], s)) ret++;
return ret;
} double getsec(Point a, Point b) {
double a1 = angle(a - cake.c);
double a2 = angle(b - cake.c);
double da = fabs(a1 - a2);
if (da > PI) da = PI * 2.0 - da;
return sqr(cake.r) * da * sgn(cross(a - cake.c, b - cake.c)) / 2.0;
} inline double gettri(Point a, Point b) { return cross(a - cake.c, b - cake.c) / 2.0;}
//typedef vector<Point> VP;
const int N = ;
struct VP {
Point vex[N];
int n;
void clear() { n = ;}
void push_back(Point x) { vex[n++] = x;}
void pop_back() { n--;}
int size() { return n;}
} ; double cpint(VP pt) {
double ret = 0.0;
int n = pt.size();
Point tmp[];
pt.vex[n] = pt.vex[];
for (int i = ; i < n; i++) {
int ic = clint(Line(pt.vex[i], pt.vex[i + ]), tmp);
if (ic == ) {
if (!cake.in(pt.vex[i]) || !cake.in(pt.vex[i + ])) ret += getsec(pt.vex[i], pt.vex[i + ]);
else ret += gettri(pt.vex[i], pt.vex[i + ]);
} else if (ic == ) {
if (cake.in(pt.vex[i])) ret += gettri(pt.vex[i], tmp[]), ret += getsec(tmp[], pt.vex[i + ]);
else ret += getsec(pt.vex[i], tmp[]), ret += gettri(tmp[], pt.vex[i + ]);
} else {
if (pt.vex[i] < pt.vex[i + ] ^ tmp[] < tmp[]) swap(tmp[], tmp[]);
ret += getsec(pt.vex[i], tmp[]);
ret += gettri(tmp[], tmp[]);
ret += getsec(tmp[], pt.vex[i + ]);
}
// cout << "~~ic " << ic << ' ' << ret << endl;
}
return fabs(ret);
} bool fixpoly(VP &poly) {
double sum = 0.0;
int n = poly.size();
poly.vex[n] = poly.vex[];
for (int i = ; i < n; i++) sum += cross(poly.vex[i], poly.vex[i + ]);
if (sgn(sum) == ) return false;
if (sgn(sum) < ) reverse(poly.vex, poly.vex + n);
return true;
} void cutpoly(VP &poly, Line l, VP &ret) {
ret.clear();
int n = poly.size();
// cout << n << endl;
poly.vex[n] = poly.vex[];
for (int i = ; i < n; i++) {
if (sgn(cross(l.vec(), poly.vex[i] - l.s)) >= ) ret.push_back(poly.vex[i]);
if (sgn(cross(l.vec(), poly.vex[i] - poly.vex[i + ]))) {
Point ip = llint(l, Line(poly.vex[i], poly.vex[i + ]));
// cout << "ip " << ip.x << ' ' << ip.y << endl;
if (onseg(ip, poly.vex[i], poly.vex[i + ]) || poly.vex[i] == ip) ret.push_back(ip);
}
}
// cout << "cp sz " << ret.size() << endl;
} const int M = ;
int q[], qh, qt, nu;
VP rec[M];
queue<int> recycle; int getID() {
int ret;
if (nu >= M) {
if (recycle.empty()) { puts("shit!"); while () ;}
ret = recycle.front();
recycle.pop();
} else ret = nu++;
return ret;
} void retID(int x) { recycle.push(x);} int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
int T, n, tmp;
double x, y;
cin >> T;
while (T-- && cin >> n) {
while (!recycle.empty()) recycle.pop();
qh = qt = nu = ;
tmp = getID();
rec[tmp].clear();
rec[tmp].push_back(Point(-R * 2.0, -R * 2.0));
rec[tmp].push_back(Point(R * 2.0, -R * 2.0));
rec[tmp].push_back(Point(R * 2.0, R * 2.0));
rec[tmp].push_back(Point(-R * 2.0, R * 2.0));
fixpoly(rec[tmp]);
q[qt++] = tmp;
for (int i = ; i < n; i++) {
cin >> x >> y;
int sz = qt - qh;
Line t = Line(cake.point(x), cake.point(y));
// cout << cake.point(x).x << '=' << cake.point(x).y << endl;
// cout << cake.point(y).x << '~' << cake.point(y).y << endl;
for (int j = ; j < sz; j++) {
tmp = getID();
// cout << "qh ?? " << qh << ' ' << q[qh] << ' ' << rec[q[qh]].size() << endl;
cutpoly(rec[q[qh]], t, rec[tmp]);
if (fixpoly(rec[tmp])) {
// cout << j << "~~1 " << rec[tmp].size() << endl;
// for (int k = 0; k < rec[tmp].size(); k++) cout << rec[tmp].vex[k].x << ' ' << rec[tmp].vex[k].y << endl;
q[qt++] = tmp;
}
swap(t.s, t.t);
tmp = getID();
cutpoly(rec[q[qh]], t, rec[tmp]);
if (fixpoly(rec[tmp])) {
// cout << j << "~~2 " << rec[tmp].size() << endl;
// for (int k = 0; k < rec[tmp].size(); k++) cout << rec[tmp].vex[k].x << ' ' << rec[tmp].vex[k].y << endl;
q[qt++] = tmp;
}
retID(q[qh++]);
}
// cout << "sz~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " << qt - qh << endl;
}
double mx = 0.0;
while (qh < qt) {
mx = max(mx, cpint(rec[q[qh++]]));
// cout << ".. " << mx << endl;
}
printf("%.2f\n", mx);
}
return ;
} /*
6
2
-3.140000 0.000000
-1.000000 1.000000
2
-3.141592 0.000000
-1.570796 1.570796
3
-3.000000 3.000000
-2.000000 2.000000
-1.000000 1.000000
4
-3.140000 0.000000
-1.000000 1.000000
-3.140000 -1.000000
1.000000 0.000000
6
-3.140000 0.000000
-1.000000 1.000000
-3.140000 -1.000000
1.000000 0.000000
-3.140000 -1.000000
1.000000 0.000000
6
-3.141592 0.000000
-1.570796 1.570796
-3.141592 -1.570796
0.000000 1.570796
-3.141592 1.570796
0.000000 -1.570796
*/

PSLG的方法将尽快更新上来!

UPD:

  模拟遍历边界,985ms压线过,因为有圆弧,所以有几个特判。比较好奇别人那些稳稳的不超时除了少用了STL还做了些什么?

代码如下:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <set> using namespace std; const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);} struct Point {
double x, y;
int id;
Point() {}
Point(double x, double y) : x(x), y(y) {}
bool operator < (Point a) const { return sgn(x - a.x) < || sgn(x - a.x) == && y < a.y;}
bool operator == (Point a) const { return sgn(x - a.x) == && sgn(y - a.y) == ;}
Point operator + (Point a) { return Point(x + a.x, y + a.y);}
Point operator - (Point a) { return Point(x - a.x, y - a.y);}
Point operator * (double p) { return Point(x * p, y * p);}
Point operator / (double p) { return Point(x / p, y / p);}
} ; inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
inline double veclen(Point x) { return sqrt(dot(x, x));}
inline Point vecunit(Point x) { return x / veclen(x);}
inline Point normal(Point x) { return Point(-x.y, x.x) / veclen(x);} const int N = ;
Point pts[N * N];
int ptcnt; struct Line {
Point s, t;
Line() {}
Line(Point s, Point t) : s(s), t(t) {}
Point vec() { return t - s;}
Point point(double p) { return s + vec() * p;}
} ; inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == && sgn(dot(a - x, b - x)) <= ;}
inline bool onseg(Point x, Line l) { return onseg(x, l.s, l.t);} const double R = 10.0;
inline bool oncircle(Point x) { return sgn(veclen(x) - R) == ;}
inline Point getpt(double p) { return Point(cos(p) * R, sin(p) * R);}
inline double angle(Point x) { return atan2(x.y, x.x);} struct Node {
double ang;
int id;
bool arc;
Node() {}
Node(double ang, int id) : ang(ang), id(id) { arc = false;}
bool operator < (Node x) const { return sgn(ang - x.ang) < || sgn(ang - x.ang) == && arc > x.arc;}
} ;
Line cut[N]; const double PI = acos(-1.0);
template<class T> T sqr(T x) { return x * x;}
Point ori, tmp[N << ];
vector<Node> nb[N * N], oc;
typedef pair<int, int> PII;
typedef pair<int, bool> PIB;
set<PII> used;
map<int, PIB> nx[N * N], anx[N * N]; inline double caltri(Point a, Point b) { return cross(a, b) / 2.0;}
double calsec(Point a, Point b) {
double da = atan2(b.y, b.x) - atan2(a.y, a.x);
da += da < ? PI * 2.0 : 0.0;
return sqr(R) * da / 2.0;
} int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
int T, n;
double s, t;
Point ip;
scanf("%d", &T);
while (T-- && ~scanf("%d", &n)) {
ptcnt = ;
used.clear();
for (int i = ; i < n; i++) {
scanf("%lf%lf", &s, &t);
cut[i] = Line(getpt(s), getpt(t));
pts[ptcnt++] = getpt(s);
pts[ptcnt++] = getpt(t);
for (int j = ; j < i; j++) {
if (sgn(cross(cut[i].vec(), cut[j].vec()))) {
ip = llint(cut[i], cut[j]);
// cout << "ip " << ip.x << ' ' << ip.y << endl;
if (onseg(ip, cut[i])) pts[ptcnt++] = ip;
}
}
}
// cout << "pt " << ptcnt << endl;
sort(pts, pts + ptcnt);
ptcnt = unique(pts, pts + ptcnt) - pts;
// cout << "npt " << ptcnt << endl;
for (int i = ; i <= ptcnt; i++) nb[pts[i - ].id = i].clear(), nx[i].clear(), anx[i].clear();
int ptn;
for (int i = ; i < n; i++) {
ptn = ;
for (int j = ; j <= ptcnt; j++) {
if (onseg(pts[j - ], cut[i])) tmp[ptn++] = pts[j - ];
}
sort(tmp, tmp + ptn);
for (int j = ; j < ptn; j++) {
nb[tmp[j].id].push_back(Node(angle(tmp[j - ] - tmp[j]), tmp[j - ].id));
nb[tmp[j - ].id].push_back(Node(angle(tmp[j] - tmp[j - ]), tmp[j].id));
}
}
oc.clear();
for (int i = ; i <= ptcnt; i++) if (oncircle(pts[i - ])) oc.push_back(Node(angle(pts[i - ]), i));
sort(oc.begin(), oc.end());
// for (int i = 0; i < oc.size(); i++) cout << oc[i].id << ' '; cout << endl;
oc.push_back(oc[]);
for (int i = , sz = oc.size(); i < sz; i++) {
nb[oc[i].id].push_back(Node(angle(pts[oc[i - ].id - ] - pts[oc[i].id - ]), oc[i - ].id));
nb[oc[i].id][nb[oc[i].id].size() - ].arc = true;
nb[oc[i - ].id].push_back(Node(angle(pts[oc[i].id - ] - pts[oc[i - ].id - ]), -oc[i].id));
nb[oc[i - ].id][nb[oc[i - ].id].size() - ].arc = true;
}
for (int i = ; i <= ptcnt; i++) {
sort(nb[i].begin(), nb[i].end());
// cout << i << " : " << pts[i - 1].x << ' ' << pts[i - 1].y << endl;
nb[i].push_back(nb[i][]);
// for (int j = 0; j < nb[i].size(); j++) cout << nb[i][j].id << '-' << nb[i][j].arc << ' '; cout << endl;
for (int j = , sz = nb[i].size(); j < sz; j++) {
if (nb[i][j].id < ) continue;
if (nb[i][j].arc) {
if (nb[i][j - ].arc) { if (j < nb[i].size() - ) nx[nb[i][j + ].id][i] = PIB(abs(nb[i][j - ].id), true), j++; else nx[nb[i][].id][i] = PIB(abs(nb[i][j - ].id), true);}
else anx[nb[i][j].id][i] = PIB(abs(nb[i][j - ].id), false);
} else {
if (!nb[i][j - ].arc || nb[i][j - ].id < ) nx[nb[i][j].id][i] = PIB(abs(nb[i][j - ].id), nb[i][j - ].arc);
}
}
nb[i].pop_back();
}
// for (int i = 1; i <= ptcnt; i++) {
// if (anx[i].size()) cout << anx[i].size() << '~' << (*anx[i].begin()).first << '~' << (*anx[i].begin()).second.first << ' ' << nx[i].size() << endl;
// else puts("~~~");
// }
double mx = 0.0, area;
int ls, cur;
PIB tt;
bool arc;
for (int i = ; i < ptcnt; i++) {
for (int j = , sz = nb[i].size(); j < sz; j++) {
if (nb[i][j].arc) continue;
ls = i, cur = nb[i][j].id;
if (used.find(PII(ls, cur)) != used.end()) continue;
arc = false;
area = caltri(pts[ls - ], pts[cur - ]);
used.insert(PII(ls, cur));
// cout << "start " << ls << ' ';
int cnt = ;
while (cur != i && cnt--) {
// cout << cur << ' ';
if (arc) tt = anx[ls][cur];
else tt = nx[ls][cur];
ls = cur, cur = tt.first, arc = tt.second;
if (arc) area += calsec(pts[ls - ], pts[cur - ]);
else area += caltri(pts[ls - ], pts[cur - ]), used.insert(PII(ls, cur));
}
// cout << area << endl;
mx = max(mx, fabs(area));
}
}
printf("%.2f\n", mx);
}
return ;
}

——written by Lyon

poj 3743 LL’s cake (PSLG,Accepted)的更多相关文章

  1. POJ 3743 LL’s cake(圆+PSLG)

    题意是给你一块在原点半径为10的圆,然后告诉你一条直线在圆弧上的极角,相当于用这条直线把这个圆分成两半,然后一共是n条直线切圆,就好比切蛋糕,问你其中最大一块的面积是多少. 如果我们将圆弧转化成直线边 ...

  2. POJ 2828 Buy Tickets(排队问题,线段树应用)

    POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意:  排队买票时候插队.  给出一些数对,分别代表某个人的想要插入的位 ...

  3. POJ 2135 Farm Tour (网络流,最小费用最大流)

    POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...

  4. POJ 2516 Minimum Cost (网络流,最小费用流)

    POJ 2516 Minimum Cost (网络流,最小费用流) Description Dearboy, a goods victualer, now comes to a big problem ...

  5. POJ 3159 Candies(差分约束,最短路)

    Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 20067   Accepted: 5293 Descrip ...

  6. POJ 3259 Wormholes(最短路,判断有没有负环回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24249   Accepted: 8652 Descri ...

  7. POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)

    http://poj.org/problem?id=2175 Evacuation Plan Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. [ACM] POJ 3687 Labeling Balls (拓扑排序,反向生成端)

    Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10161   Accepted: 2810 D ...

  9. POJ 3154 Graveyard【多解,数论,贪心】

    Graveyard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1707   Accepted: 860   Specia ...

随机推荐

  1. 2019-2-14-VisualStudio-通过外部调试方法快速调试库代码

    title author date CreateTime categories VisualStudio 通过外部调试方法快速调试库代码 lindexi 2019-2-14 22:1:37 +0800 ...

  2. django中模板

    一.创建模板目录和模板html文件 # /templates/应用名称/html文件集合 #模板目录:创建项目根目录下面,和manage.py工具在同一层#在模板目录下面分别创建各个应用的模板目录#最 ...

  3. 表格存储TableStore2.0重磅发布,提供更强大数据管理能力

    表格存储TableStore是阿里云自研的面向海量结构化和半结构化数据存储的Serverless NoSQL多模型数据库,被广泛用于社交.物联网.人工智能.元数据和大数据等业务场景.表格存储Table ...

  4. HTML 5+ SDK 更新日志

    http://ask.dcloud.net.cn/article/103 离线打包 SDK App 最新Andorid平台SDK下载新版本Android SDK使用aar方式发布,部分资源和jar包整 ...

  5. lingo 出现63. MODEL IS ILL DEFINED 解决办法

    63. MODEL IS ILL DEFINED. CHECK FOR UNDEFINED INDICES AND/OR CONDITIONS IN EXPRESSION: EXPRESSION. 还 ...

  6. Bundler和Minifier Visual Studio扩展

    原文地址:https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BundlerMinifier 特征 将CSS,Java ...

  7. JS函数式编程 - 概念

    最近在看Typescript,顺便看了一些函数式编程,然后半个国庆假期就没有了.做个笔记,分几个部分写吧. 最开始接触函数式编程的时候,第一个接触的概念就是高阶函数,和柯里化.咋一看,这不就是长期用来 ...

  8. iOS音频篇:使用AVPlayer播放网络音乐

    http://www.cocoachina.com/ios/20160324/15767.html 引言 假如你现在打算做一个类似百度音乐.豆瓣电台的在线音乐类APP,你会怎样做? 首先了解一下音频播 ...

  9. 弘康人寿基于 RocketMQ 构建微服务边界总线的实践

    随着互联网+和平台化战略的兴起,各个行业的 IT 系统都在向互联网架构发展,涉及的主要技术包括微服务.消息和弹性计算等,采用微服务架构实现服务高内聚.低耦合,通过异步消息完成交易快速响应和高并发.由于 ...

  10. JQuery-- 获取元素的宽高、获取浏览器的宽高和垂直滚动距离

    * 能够使用jQuery设置尺寸 * .width() width * .innerWidth() width + padding * .outerWidth() width + padding + ...