UVA 11177 凸多边形和圆交
2015-10-02 15:46
225 查看
#define _USE_MATH_DEFINES #include <cstdio> #include <cmath> #include <vector> #include <algorithm> using namespace std; struct Vertex { double x, y; }; int vc; Vertex vs[64]; double dis[64]; enum ItType { N, IO, OI }; struct IVtx { Vertex v; ItType t; }; bool inside(double x) { const double eps = 1e-8; return 0 - eps < x && x < 1 + eps; } int GetIt(Vertex &va, Vertex &vb, double r, double &t0, double &t1) { const double eps = 1e-8; double A = (vb.x - va.x)*(vb.x - va.x) + (vb.y - va.y)*(vb.y - va.y); double B = 2 * (va.x*(vb.x - va.x) + va.y*(vb.y - va.y)); double C = va.x*va.x + va.y*va.y - r * r; double delta = B * B - 4 * A * C; if (delta < -eps) return 0; else if (delta < eps) { t0 = -B / (2 * A); return inside(t0) ? 1 : 0; } else { double sd = sqrt(delta); t0 = (-B - sd) / (2 * A); int rc = 0; if (inside(t0)) { rc++; t1 = (-B + sd) / (2 * A); if (inside(t1)) rc++; } else { t0 = (-B + sd) / (2 * A); if (inside(t0)) rc++; } return rc; } } void GetArea(vector<IVtx> &ia, double r) { for (int i = 0; i < vc; i++) { IVtx it; Vertex k; Vertex &va = vs[i], &vb = vs[(i + 1) % vc]; double t0, t1; if (dis[i] >= r * r || dis[(i + 1) % vc] >= r * r) { switch (GetIt(va, vb, r, t0, t1)) { case 0: break; // no It case 1: k.x = va.x + (vb.x - va.x) * t0; k.y = va.y + (vb.y - va.y) * t0; it.v = k; if (dis[i] <= r * r && dis[(i + 1) % vc] >= r * r) { it.t = IO; ia.push_back(it); } else if (dis[i] >= r * r && dis[(i + 1) % vc] <= r * r) { it.t = OI; ia.push_back(it); } else ;// pass break; case 2: k.x = va.x + (vb.x - va.x) * t0; k.y = va.y + (vb.y - va.y) * t0; it.v = k; it.t = OI; ia.push_back(it); k.x = va.x + (vb.x - va.x) * t1; k.y = va.y + (vb.y - va.y) * t1; it.v = k; it.t = IO; ia.push_back(it); break; } } else { it.t = N; it.v = va; ia.push_back(it); it.v = vb; ia.push_back(it); } } } double TriArea(Vertex a, Vertex b/*, Vertex c*/) { //return (a.x - c.x)*(b.y - c.y) - (a.y - c.y)*(b.x - c.x); //c(0,0) return a.x * b.y - a.y * b.x; } double CalcArea(double r) { vector<IVtx> its; GetArea(its, r); if (its.empty()) return M_PI * r * r; else { double ans = 0; int c = its.size(); for (int i = 0; i < c; i++) { if (its[i].t == IO && its[(i + 1) % c].t == OI) { double t0 = atan2(its[i].v.y, its[i].v.x); double t1 = atan2(its[(i + 1) % c].v.y, its[(i + 1) % c].v.x); double p = max(t0, t1) - min(t0, t1); p = min(p, M_PI * 2 - p); ans += p / 2 * r * r; } else ans += abs(TriArea(its[i].v, its[(i + 1) % c].v) / 2); } return ans; } } int main() { int tc = 1; while (scanf("%d", &vc) != EOF && vc) { double area; scanf("%lf", &area); double maxdis = 0; for (int i = 0; i < vc; i++) { scanf("%lf%lf", &vs[i].x, &vs[i].y); dis[i] = vs[i].x * vs[i].x + vs[i].y * vs[i].y; maxdis = max(maxdis, dis[i]); } const double eps = 1e-3; double l = 0, r = maxdis; while (abs(r - l) > eps) { double m = (r + l) / 2; double a = CalcArea(m); if (a > area) r = m; else l = m; } printf("Case %d: %.2lf\n", tc++, (l + r) / 2); } return 0; }
UVA 11177 二分半径求重合面积
相关文章推荐
- 查找二叉树
- SQL常用命令
- HDU - 1200 To and Fro(水)
- 数据库的优化
- 枚举类型的基本用法
- Matlab基础知识
- Extjs4.2 model关联读复杂XML
- 面试题22:栈的压入、弹出序列
- vfork http://blog.csdn.net/tennysonsky/article/details/45847107
- BZOJ 3531 旅行【树链剖分】
- 数据库最最常用语句(10年工作笔记)
- java抽象类
- 如何在Linux上使用netstat命令查证DDOS攻击
- android布局属性大全
- 安卓控件使用系列12:CheckBox复选框控件的使用
- 轮廓线动态规划问题
- swift闭包
- iOS 多线程实例(NSThread售票窗口的模拟)
- web前端性能优化
- ZOJ - 2421 Recaman's Sequence(打表水题)