题目
题目背景
在 Nescafe27 和 28 中,讲述了一支探险队前往 Nescafe 之塔探险的故事……
当两位探险队员以最快的时间把礼物放到每个木箱里之后,精灵们变身为一缕缕金带似的光,簇簇光芒使探险队员们睁不开眼睛。待一切平静下来之后,探险队员来到了一座宫殿 中,玉制的石椅上坐着两个人……
“你们就是……Nescafe 之塔护法中的两位?”
“是的,我们就是神刀护法 xlk 和飞箭护法 riatre……你们来这里做什么?”
“我们是前来拜访圣主和四位护法的……”
“如果你们想见圣主和其它两位护法,你们必须穿过前方的七色彩虹。请随我来吧……”
题目描述
探险队员们跟随两位护法来到了七色虹前。七色虹,就是平面直角坐标系中赤橙黄绿青 蓝紫七个半圆,第 i 座(1<=i<=7)半圆形彩虹的圆心是(xi,0),半径是 ri,半圆上所有点的纵坐 标均为非负数。探险队员可以看做一条竖直的、长度等于身高的线段,线段的底端纵坐标为 0,最高的一位探险队员的身高为 h。
现在探险队员们要从(0,0)穿越七色虹到达(x0,0),穿越七色虹的过程中,探险队员的整 个身体必须始终在至少一个半圆形彩虹的内部。由于彩虹的半径 ri 可能太小了,不足以满 足这个条件,因此两位护法决定帮助他们把所有彩虹的半径都增大一个非负实数 r。探险队 员们想知道,r 最小是多少呢?
输入格式
第一行两个实数 h、x0,表示身高和目的地横坐标。
接下来七行每行两个实数 xi、ri,表示七座半圆形彩虹的圆心和半径。
输出格式
输出最小的 r,四舍五入保留 2 位小数。
样例输入
4.0 36.0
0.0 4.0
6.0 4.0
12.0 4.0
18.0 4.0
24.0 4.0
30.0 4.0
36.0 4.0
样例输出
1.00
数据范围及约定
对于 100% 的数据,满足 0<=xi,x0<=10000,0<h<100。
解
穿越七彩虹
二分,没什么好说的。
代码
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 6 using namespace std; 7 8 #define EPS 1e-10 9 10 double h, x0; 11 12 struct Node { 13 double x, r; 14 }c[10]; 15 16 struct Segment { 17 double l, r; 18 }seg[10]; 19 20 bool cmp(const Segment &a, const Segment &b) { 21 return a.l < b.l; 22 } 23 24 int check(double R) 25 { 26 int segcnt = 0; 27 for(int i = 1; i <= 7; ++i) 28 { 29 double delt = 4 * ((c[i].r + R) * (c[i].r + R) - h * h); 30 31 if(delt < 0)continue; 32 double x1 = (2 * c[i].x - sqrt(delt)) / 2; 33 double x2 = (2 * c[i].x + sqrt(delt)) / 2; 34 seg[++segcnt] = (Segment){x1, x2}; 35 } 36 sort(seg + 1, seg + 1 + segcnt, cmp); 37 double r = 0; 38 for(int i = 1; i <= segcnt && r < x0; ++i) 39 { 40 if(seg[i].l > r) 41 break; 42 else 43 r = max(r, seg[i].r); 44 } 45 if(r < x0) 46 return 0; 47 else 48 return 1; 49 } 50 51 int main() { 52 freopen("rainbow.in", "r", stdin); 53 freopen("rainbow.out", "w", stdout); 54 55 scanf("%lf%lf", &h, &x0); 56 57 for(int i = 1; i <= 7; ++i) 58 scanf("%lf%lf", &c[i].x, &c[i].r); 59 60 double l = 0.0, r = 10000.0, mid; 61 while(r - l >= EPS) { 62 mid = (l + r) / 2; 63 if(check(mid)) 64 r = mid; 65 else 66 l = mid; 67 } 68 69 printf("%.2lf\n", mid); 70 71 fclose(stdin); 72 fclose(stdout); 73 74 return 0; 75 }
原文地址:https://www.cnblogs.com/fl0w3r/p/9920604.html