2018.11.7 Nescafe29 T1 穿越七色虹

题目

题目背景

在 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
", mid);
70     
71     fclose(stdin);
72     fclose(stdout);
73     
74     return 0;
75 }
原文地址:https://www.cnblogs.com/fl0w3r/p/9920604.html