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. Angungular.js 的过滤器&工具方法

    字母大小写 数字 货币 截取字符串 截取数组 用JS操作 ----------------------------------------------------------------------- ...

  2. JavaScript Libraries In A TypeScript Application, Revisited

    If you haven’t already gotten involved with it, you’ll probably know that TypeScript is becoming inc ...

  3. IntelliJ IDEA中设置同时打开多个文件且分行显示

    [转载]原文链接:https://blog.csdn.net/lwl20140904/article/details/73275897 有时候要是打开多个文件,要么都显示在一行,要么因为空间不足,就给 ...

  4. 阿里云Global Connection亮相MWC 2019,做企业全球化开路先锋

    上周在巴塞罗那举行的MWC 2019世界移动通信大会上,阿里云发布了包含Global Connection解决方案在内的7款重量级产品和解决方案,为全球企业提供了基于阿里云的智能化企业数字转型思路.G ...

  5. excel怎么并排查看两个工作表

    excel怎么并排查看两个工作表 excel怎么并排查看两个工作表?excel打开一个窗口想要同时查看两个工作表中的数据,类似于word中的分栏效果,该怎么实现呢?EXCEL是一个使用最多的办公软件, ...

  6. Legal or Not HDU - 3342 (拓扑排序)

     注意点: 输入数据中可能有重复,需要进行处理! #include <stdio.h> #include <iostream> #include <cstring> ...

  7. <第一周>降维

    PCA 矩阵的主成分就是其协方差矩阵对应的特征向量,按照对应的特征值大小进行排序,最大的特征值为第一主成分,以此类推 主要过程 对所有样本进行中心化 计算样本的协方差矩阵 XX.T 对协方差矩阵做特征 ...

  8. 三.BP神经网络

    BP神经网络是包含多个隐含层的网络,具备处理线性不可分问题的能力.以往主要是没有适合多层神经网络的学习算法,,所以神经网络的研究一直处于低迷期. 20世纪80年代中期,Rumelhart,McClel ...

  9. Asterisk项目概述

    Asterisk是一个开源的软件包,通常运行在Linux操作系统平台上.Asterisk可以用三种协议来实现VoIP,同时可以与目前电话使用的标准硬件进行交互通信,Asterisk在实现VoIP时,不 ...

  10. 操作系统之LRU算法 C语言链表实现

    LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰.该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历 ...