CodeForces - 1059D——二分/三分
题目
简单的说,就是作一个圆包含所有的点且与x轴相切,求圆的最小半径
方法一
分析:求最小,对半径而言肯定满足单调性,很容易想到二分。我们二分半径,然后由于固定了与X轴相切,我们对于每一个点,就可以算出这个点在圆上的时候圆与x轴相交的距离(其实就是圆心的x轴的范围)。然后对每个点都可以求一个圆心的横坐标区间,如果所有的区间有相交区域,则该半径满足条件,否则不满足。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; const int maxn = + ;
const double esp = 1e-;
struct Piont
{
double x, y;
}p[maxn];
int n; bool judge(double r)
{
double ml = -1e15, mr = 1e15;
for (int i = ; i < n; i++)
{
if (p[i].y > * r) return false; //大于2倍半径的,肯定不行
double tmp = sqrt( * p[i].y * r - p[i].y * p[i].y);
if (p[i].x - tmp > ml) ml = p[i].x - tmp;
if (p[i].x + tmp < mr) mr = p[i].x + tmp;
}
return ml <= mr; //所有区间必须要有交点
} int main()
{
while (scanf("%d", &n) == )
{
int flag1 = , flag2 = ;
for (int i = ; i < n; i++)
{
scanf("%lf%lf", &p[i].x, &p[i].y);
if (p[i].y > ) flag1 = ;
if (p[i].y < ) flag2 = ;
if (p[i].y < ) p[i].y = -p[i].y;
}
if (flag1 && flag2)
{
printf("-1\n");
continue;
} double l = , r = 1e15, mid; //直接枚举圆的半径,范围大约是1e7的平方
int cnt = ; //二分100次精度足够了
while (cnt--) //这里写成(r - l) < esp陷入了死循环。。。
{
mid = (r + l) / 2.0;
if (judge(mid)) r = mid;
else l = mid;
}
printf("%.10lf\n", r);
}
return ;
}
方法二
分析:设圆心的横坐标为x,由勾股定理有(x-x0)2 + (r-y)2 = r2,得r = (x-x0)2/2y + y/2,所以R = max(r1,r2,,,rn),也就是说x确定时,R也随之确定。
我们又发现,对于答案所在得X,在它左右走R都会单调递增,形成像山谷那样得形状,那么直接三分X直接找到谷底即可。
具体的三分做法如下:
设答案所在区间为(l,r),dx = (r-l)/3,则mr = r+dx,ml = l-dx。设cal(x)是计算圆心在x时r的值,若cal(ml) < cal(mr),有两种情况,异侧如①,同侧如③,所以将r更新为mr,而不是更新为ml,同理,若cal(ml) > cal(mr),则将l更新为ml。

代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = + ;
const double esp = 1e-;
struct Piont
{
double x, y;
}p[maxn];
int n; double cal(double x)
{
double r = ;
for (int i = ; i < n; i++)
r = max(r, p[i].y / 2.0 + (x - p[i].x) * (x - p[i].x) / p[i].y / 2.0);
return r;
} int main()
{
while (scanf("%d",&n) == )
{
int flag1 = , flag2 = ;
for (int i = ; i < n; i++)
{
scanf("%lf%lf", &p[i].x, &p[i].y);
if (p[i].y > ) flag1 = ;
if (p[i].y < ) flag2 = ;
if (p[i].y < ) p[i].y = -p[i].y;
}
if (flag1 && flag2)
{
printf("-1\n");
continue;
}
//R=y1/2 + (x-x1)^2/2y,x是圆心坐标,R关于x先减后增
double l = -1e7, r = 1e7,dx; //枚举圆的半径,也就是枚举圆心横坐标
while (r - l > esp) //也可改成cnt<100
{
dx = (r - l) / 3.0;
double lx = l + dx, rx = r - dx;
if (cal(lx) - cal(rx) < ) r = rx;
else l = lx;
}
int tmp = cal(r);
printf("%.6lf\n", cal(r));
}
return ;
}
参考链接:
https://blog.csdn.net/lzc504603913/article/details/82949923
https://blog.csdn.net/qq_37555704/article/details/82949337
http://www.cnblogs.com/sdfzhsz/p/9748360.html
https://blog.csdn.net/winter2121/article/details/82949159?tdsourcetag=s_pctim_aiomsg
CodeForces - 1059D——二分/三分的更多相关文章
- CodeForces - 1059D(二分+误差)
链接:CodeForces - 1059D 题意:给出笛卡尔坐标系上 n 个点,求与 x 轴相切且覆盖了所有给出点的圆的最小半径. 题解:二分半径即可.判断:假设当前二分到的半径是 R ,因为要和 x ...
- Codeforces 939E Maximize ( 三分 || 二分 )
题意 : 给出两个操作,① 往一个序列集合(初始为空)里面不降序地添加数字.② 找出当前序列集合的一个子集使得 (子集的最大元素) - (子集的平均数) 最大并且输出这个最大差值 分析 : 首先关注 ...
- 第二次组队赛 二分&三分全场
网址:CSUST 7月30日(二分和三分) 这次的比赛是二分&三分专题,说实话以前都没有接触过二分,就在比赛前听渊神略讲了下.......不过做着做着就对二分熟悉了,果然做题是学习的好方法啊~ ...
- Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...
- HDU 2298 Toxophily 【二分+三分】
一个人站在(0,0)处射箭,箭的速度为v,问是否能够射到(x,y)处,并求最小角度. 首先需要判断在满足X=x的情况下最大高度hmax是否能够达到y,根据物理公式可得 h=vy*t-0.5*g*t*t ...
- CF 8D Two Friends 【二分+三分】
三个地点构成一个三角形. 判断一下两个人能否一起到shop然后回家,如果不能: 两个人一定在三角形内部某一点分开,假设沿着直线走,可以将问题简化. 三分从电影院出来时候的角度,在对应的直线上二分出一个 ...
- CodeForces - 363D --二分和贪心
题目:CodeForces - 363D 题意:给定n个学生,其中每个学生都有各自的私己钱,并且自己的私己钱只能用在自己买自行车,不能给别人. 给定m个自行车,每个自行车都有一个价格. 给定公有财产a ...
- Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论
n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...
- Toxophily-数论以及二分三分
G - Toxophily Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submi ...
随机推荐
- 「LuoguP3384」【模板】树链剖分
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- table中tr或者td的点击事件
直接把时间添加到table或者tbody上,只有下面的tr或者td才能促发事件,通过e.target可以获得当前点击tr或者td,这样就可以进行查询或者删除操作了 如果是删除,直接e.target.r ...
- MYSQL数据库学习----插入、更新、删除
一:插入数据 1 为表的所有字段插入数据 INSERT INTO 表名 (值1,值2, 值3...); 2 为表的指定字段插入数据 INSERT INTO 表名(字段1,字段2,...) VALUES ...
- bzoj2676
二分概率+矩乘+dp 也是二分概率,然后dp[i][j][k]表示当前到了i,有j条命,下一次的收益是k,然后矩乘转移,但是我自己的似乎wa了,抄了liu_runda的才行,具体不知道为什么 注释的是 ...
- IOS 的调试模式
iOS调试模式分为: 断点单步调试: 全局断点调试: 僵尸调试: 暴力调试: 这里主要说一下什么是僵尸调试模式? .为什么会使用NSZombieEnabled? 应用调试可能会收到类似 Thread ...
- 最优灌溉_最小生成树Kruskal
问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉. 为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中 ...
- 所读STL文章摘要集结
在网上看了一些STL相关文章,这里将它们的摘要进行集结,方便以后查找. 1.黄常标,林俊义,江开勇.快速成形中STL文件拓扑信息的快速建立.2004 摘要:在分析现有建立拓扑信息方法的基础上,提出基于 ...
- JAVA基础-面向对象05
一.面向对象的引入 解决问题的时候,首先要会分析思路,这个思路就是我们生活中解决一个问题的方法步骤: 有了思路之后,再把思路使用java代码来解决: 但是 计算总分的需求变了 分析:原来在一个程序中, ...
- rbenv的使用
创建: 2017/09/05 更新: 2018/02/03 增加更新rbenv和获取list没有的版本 更新: 2018/02/25 把path里面[个人主机名]全部替换为[主机名] 更新: 2018 ...
- “玲珑杯”线上赛 Round #17 河南专场 A: Sin your life(和化积公式)
传送门 题意 略 分析 首先将sin(x)+sin(y)+sin(z)h转化成\(2*sin(\frac{x+y}2)*cos(\frac{x-y}2)+sin(z)\),而cos(z)=cos(-z ...