ACM-ICPC Live Archive

  挺水的一道题,直接二分圆的半径即可。1y~

  类似于以前半平面交求核的做法,假设半径已经知道,我们只需要求出线段周围哪些位置是不能放置圆心的即可。这样就转换为圆与直线,直线与直线交的问题了。

  不知道这题能不能SAA过,有空试下。

代码如下:

 #include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
typedef pair<double, double> Point;
#define x first
#define y second
template<class T> T sqr(T x) { return x * x;}
Point operator + (Point a, Point b) { return Point(a.x + b.x, a.y + b.y);}
Point operator - (Point a, Point b) { return Point(a.x - b.x, a.y - b.y);}
Point operator * (Point a, double p) { return Point(a.x * p, a.y * p);}
Point operator / (Point a, double p) { return Point(a.x / p, a.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 a) { return sqrt(dot(a, a));}
inline Point vecunit(Point a) { return a / veclen(a);}
inline Point normal(Point a) { return Point(-a.y, a.x) / veclen(a);} 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;}
Line move(double p) { // + left - right
Point nor = normal(vec());
return Line(s + nor * p, t + nor * p);
}
} ; inline bool between(Point o, Point a, Point b) { return sgn(dot(a - o, b - o)) < ;}
inline bool between(Point a, Line l) { return between(a, l.s, l.t);}
inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));} bool clint(Point a, double r, double *sol) {
if (sgn(r - fabs(a.y)) <= ) return ;
double d = sqrt(sqr(r) - sqr(a.y));
//cout << "d " << d << endl;
sol[] = a.x - d;
sol[] = a.x + d;
return ;
} Line Y0 = Line(Point(, ), Point(, )); double L;
inline void adjust(double &x) { x = max(0.0, min(L, x));}
Point getseg(Line a, double r) {
vector<double> sol;
sol.clear();
double t[];
if (clint(a.s, r, t)) sol.push_back(t[]), sol.push_back(t[]);
if (clint(a.t, r, t)) sol.push_back(t[]), sol.push_back(t[]);
Line l1 = a.move(r), l2 = a.move(-r), l3 = Line(l1.s, l2.s), l4 = Line(l1.t, l2.t);
Point p1 = llint(l1, Y0), p2 = llint(l2, Y0), p3 = llint(l3, Y0), p4 = llint(l4, Y0);
if (between(p1, l1)) sol.push_back(p1.x);
if (between(p2, l2)) sol.push_back(p2.x);
if (between(p3, l3)) sol.push_back(p3.x);
if (between(p4, l4)) sol.push_back(p4.x);
if (sol.size() == ) return Point(-, -);
sort(sol.begin(), sol.end());
//cout << "sol ";
//for (int i = 0; i < sol.size(); i++) cout << sol[i] << ' '; cout << endl;
adjust(sol[]), adjust(sol[sol.size() - ]);
return Point(sol[], sol[sol.size() - ]);
} const int N = ;
typedef pair<double, int> Event;
Line l[N];
int n; bool test(double r) {
vector<Event> ev;
ev.clear();
for (int i = ; i < n; i++) {
Point tmp = getseg(l[i], r);
if (tmp.x < || tmp.y < ) continue;
//cout << tmp.x << '~' << tmp.y << endl;
ev.push_back(Event(tmp.x, ));
ev.push_back(Event(tmp.y, -));
}
sort(ev.begin(), ev.end());
//cout << r << endl;
//for (int i = 0; i < ev.size(); i++) cout << ev[i].x << '&' << ev[i].y << ' '; cout << endl;
double last = ;
int cnt = , sz = ev.size();
for (int i = ; i < sz; i++) {
if (ev[i].y == ) {
if (cnt == && sgn(ev[i].x - last) > ) return ;
cnt++;
} else {
if (cnt == ) last = ev[i].x;
cnt--;
}
}
return sgn(L - last) > ;
} int main() {
//freopen("in", "r", stdin);
int T;
cin >> T;
while (T-- && cin >> n >> L) {
for (int i = ; i < n; i++) cin >> l[i].s.x >> l[i].s.y >> l[i].t.x >> l[i].t.y;
double lp = , rp = , mp;
while (rp - lp > EPS) {
mp = (lp + rp) / ;
if (test(mp)) lp = mp;
else rp = mp;
}
//puts("~~~~~~~~~~~~~~~~~~~~~~~~");
//test(2.118);
printf("%.3f\n", mp);
}
return ;
}

——written by Lyon

4818 Largest Empty Circle on a Segment (几何+二分)的更多相关文章

  1. uva 1463 - Largest Empty Circle on a Segment(二分+三分+几何)

    题目链接:uva 1463 - Largest Empty Circle on a Segment 二分半径,对于每一个半径,用三分求出线段到线段的最短距离,依据最短距离能够确定当前R下每条线段在[0 ...

  2. UVALive 4818 - Largest Empty Circle on a Segment (计算几何)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  3. Project Euler 363 Bézier Curves(几何+二分)

    题目链接: https://projecteuler.net/problem=363 题目: A cubic Bézier curve is defined by four points: \(P_0 ...

  4. BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图

    这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...

  5. UVALive - 6856 Circle of digits 后缀数组+二分

    题目链接: http://acm.hust.edu.cn/vjudge/problem/82135 Circle of digits Time Limit: 3000MS 题意 把循环串分割成k块,让 ...

  6. 【BZOJ1822】[JSOI2010]Frozen Nova 冷冻波 几何+二分+网络流

    [BZOJ1822][JSOI2010]Frozen Nova 冷冻波 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀 ...

  7. Aquarium Tank(csu1634+几何+二分)Contest2087 - 湖南多校对抗赛(2015.05.24)-G

    Aquarium Tank Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 15  Solved: 4[Submit][Status][Web Board ...

  8. poj 2002 Squares 几何二分 || 哈希

    Squares Time Limit: 3500MS   Memory Limit: 65536K Total Submissions: 15137   Accepted: 5749 Descript ...

  9. Visulalize Boost Voronoi in OpenSceneGraph

    Visulalize Boost Voronoi in OpenSceneGraph eryar@163.com Abstract. One of the important features of ...

随机推荐

  1. java并发系列(五)-----如何正确的关闭一个线程

    正确的关闭一个线程可不是简单的事情,由于线程调度的复杂性以及不可控性(毕竟运行都由操作系统做主),先来了解一下interrupt() 1.interrupt() 根据jdk文档的介绍,如下: inte ...

  2. python元祖和列表

    下面讲到的分别有: 列表:元祖 列表的定义 list(列表)是python中使用最频繁的数据类型,在其他语言中叫做数组 专门储存一串信息 列表[  ]定义,数据之间有逗号分隔 列表的索引是从0开始的 ...

  3. Python 可变类型和不可变类型,以及其引用

    基本数据类型的引用        在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址.访问这块内存需要用到变量名,变量名实际存储的是变量的 ...

  4. 2019.10.25 csp-s模拟测试86 反思总结

    继续存档 早上来补了一下昨天的题,不过肯定这两天的没法完全补起来 T1: 经典思路:关于位运算的题讨论每一位的贡献 #include<iostream> #include<cstdi ...

  5. codevs1214 线段覆盖

    1214 线段覆盖 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold       题目描述 Description 给定x轴上的N(0<N<100)条线段, ...

  6. 用js控制video的src_百度知道

    代码如下 <section id="player"> <video id="media" width="100%" hei ...

  7. django中模型

    一.django需要使用数据库,则需要安装对应的驱动,比如mysql,则需要安装mysqlclient驱动: pip install mysqlclient 二.在settings.py文件中配置数据 ...

  8. 卡特兰数(catalan)总结

    卡特兰数的公式 递推公式1:$f(n)=\sum \limits_{i=0}^{n-1}f(i)*f(n-i-1)$ 递推公式2:$f(n)=\frac{f(n-1)*(4*n-2)}{n+1}$ 组 ...

  9. PHP 学习1.1

    1 链接mysql 数据简单测试 <html><head>  <title></title>  <meta http-equiv="Co ...

  10. agc015F Kenus the Ancient Greek

    题意: 有$Q$次询问,每次给定$X_i$和$Y_i$,求对于$1\leq x \leq X_i , 1 \leq y \leq Y_i$,$(x,y)$进行辗转相除法的步数的最大值以及取到最大值的方 ...