Problem:
夕暮れ
AIZU 国の夕暮れ時は、スマートフォンを西の空へ構えて立ち止まる観光客で賑わう。AIZU 国は無数のビルが建ち並ぶ大都市であり、ビルの谷間が長く連なる西の空には、ビルのシルエットとそれらから漏れ出す太陽の光による絶景が広がる。
AIZU 観光協会の若松氏によると、太陽を表す円が、その面積のちょうど半分だけ遮られているとき、格段の絶景になるという。
図のように、西の空を、地平線を
x
軸、太陽の中心の軌跡を
y
軸とするような
x
-
y
平面で表し、太陽を半径
R
の円、それぞれのビルのシルエットを長方形とする。
各ビルのシルエットの底辺は
x
軸上にあり、太陽は十分高い位置から地平線に対して垂直に沈んでいく。太陽はビルのシルエットあるいは地平線を上端とする地面に遮られ、やがて地平線の下へ消えてゆく。
太陽の半径と各ビルのシルエットの情報が与えられたとき、太陽の面積のちょうど半分が遮られるような、最も高い太陽の高さ（中心の
y
座標）を求めるプログラムを作成せよ。
Input
入力は以下の形式で与えられる。
N
R
x
1
w
1
h
1
x
2
w
2
h
2
:
x
N
w
N
h
N
１行目にビルの数
N
(0 ≤
N
≤ 100) と太陽を表す円の半径
R
(1 ≤
R
≤ 100) が与えられる。続く
N
行に
i
番目のビルのシルエットの左下角の
x
座標
x
i
(-100 ≤
x
i
≤ 100,
x
i
<
x
i+1
)、幅
w
i
(1 ≤
w
i
≤ 100)、高さ
h
i
(1 ≤
h
i
≤ 100) が与えられる。入力はすべて整数で与えられる。
入力は以下の条件を満たす。
ビルのシルエットが重なることはない（
x
i
+
w
i
≤
x
i+1
）。
２つの隣接するビルのシルエットの高さの差は、
R
を超えない。
ビルの左側（
x
軸の負の方向）または右側（
x
軸の正の方向）に隣接するビルがない場合、その高さは
R
を超えない。
Output
太陽の高さ（円の中心の
y
座標）を１行に出力する。ただし、誤差がプラスマイナス 10
-6
を超えてはならない。
Sample Input 1
0 2
Sample Output 1
0.00000000
Sample Input 2
3 2
-2 1 1
-1 1 2
0 2 1
Sample Output 2
1.25065774

Submitted solutions:

code_snippet: // AOJ #356
// Evening 2025.2.8

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-10;
const double PI = acos(-1.0);
 
double groundIntersection(double Y, double R) {
    double circleArea = PI * R * R;
    if(Y >= R) return 0.0;
    if(Y <= -R) return circleArea;
    if(Y >= 0) {
        double theta = acos(Y / R);
        double segArea = R * R * theta - Y * sqrt(R * R - Y * Y);
        return segArea;
    } else {
        double d = -Y; // d>0
        double theta = acos(d / R);
        double capArea = R * R * theta - d * sqrt(R * R - d * d);
        return circleArea - capArea;
    }
}
 
double simpson_rule(function<double(double)> f, double a, double b) {
    double c = (a + b) * 0.5;
    return (b - a) / 6.0 * (f(a) + 4.0*f(c) + f(b));
}
 
double adaptiveSimpson(function<double(double)> f, double a, double b, double eps, double whole) {
    double c = (a+b)/2.0;
    double left = simpson_rule(f, a, c);
    double right = simpson_rule(f, c, b);
    if(fabs(left + right - whole) <= 15 * eps)
        return left + right + (left+right - whole) / 15.0;
    return adaptiveSimpson(f, a, c, eps/2, left) + adaptiveSimpson(f, c, b, eps/2, right);
}
 
double integrate(function<double(double)> f, double a, double b, double eps=1e-8) {
    double initial = simpson_rule(f, a, b);
    return adaptiveSimpson(f, a, b, eps, initial);
}
 
double buildingIntegrand(double x, double Y, double H, double R) {
    double under = R*R - x*x;
    if(under < 0) return 0.0;
    double t = sqrt(under);
    double lowCircle = Y - t;
    double highCircle = Y + t;
    double lowInt = max(0.0, lowCircle);
    double highInt = min(H, highCircle);
    double ret = highInt - lowInt;
    return (ret > 0 ? ret : 0.0);
}
 
double buildingIntersection(double Y, double X, double w, double H, double R) {
    double xLow = max(X, -R);
    double xHigh = min(X + w, R);
    if(xHigh <= xLow) return 0.0;
    auto f = [=](double x) {
        return buildingIntegrand(x, Y, H, R);
    };
    double area = integrate(f, xLow, xHigh, 1e-8);
    return area;
}
 
struct Building {
    double x, w, h;
};
 
double totalOccludedArea(double Y, double R, const vector<Building>& buildings) {
    double area = 0.0;
    area += groundIntersection(Y, R);
    for (auto &b : buildings) {
        area += buildingIntersection(Y, b.x, b.w, b.h, R);
    }
    return area;
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int N;
    double R;
    cin >> N >> R;
    vector<Building> buildings;
    for (int i = 0; i < N; i++){
        Building b;
        cin >> b.x >> b.w >> b.h;
        buildings.push_back(b);
    }
 
    double sunArea = PI * R * R;
    double target = sunArea / 2.0;
 
    double lo = -R, hi = R + 100.0;
    for(int iter = 0; iter < 100; iter++){
        double mid = (lo + hi) / 2.0;
        double occ = totalOccludedArea(mid, R, buildings);
        double diff = occ - target;
        if(diff > 0) lo = mid;
        else         hi = mid;
    }
    double Y_ans = (lo + hi) / 2.0;
    if (fabs(Y_ans) <= eps) Y_ans = 0;
    cout << fixed << setprecision(10) << Y_ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3980
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ld=long double;
ld u;

int main(){
  int n, r; cin>>n>>r;
  u=(ld)r/500000.0;
  vector<ld> h(300);
  for(int i=0; i<n; i++){
    int x, w, H;cin>>x>>w>>H;
    for(int j=0; j<w; j++){
      h[x+105+j]=H;
    }
  }
  ld L=0, R=100;
  for(int _=0;_<30; _++){
    ld m=(L+R)/2.0;
    ld area=0;
    for(int i=-500000; i<500000; i++){
      ld x=(ld)r*i/500000.0;
      ld y=sqrt((ld)r*r-x*x)+sqrt((ld)r*r-(x+u)*(x+u)); y/=2.0;
      ld si=m-y, ue=m+y;
      ld mid=h[105+x];
      if(si<=mid&&mid<=ue) area+=(mid-si)*u;
      if(ue<mid) area+=(ue-si)*u;
    }
    if(area*2<(ld)r*r*3.1415926535897932) R=m;
    else L=m;
  }
  cout<<fixed<<setprecision(10)<<L<<endl;
}
accuracy: 0.23529411764705882
time_ms: 280
memory_kb: 3500
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

const long double PI = 3.14159265358979323L;
int N, V, A[109], B[109], C[109], E[309];

long double calc_area(vector<pair<long double, long double>>X) {
	long double G = 0;
	for (int i = 0; i < X.size(); i++) {
		G += (X[i].first - X[(i + 1) % X.size()].first) * (X[i].second + X[(i + 1) % X.size()].second);
	}
	return 0.5L * abs(G);
}

long double calc_kakudo(long double x, long double y) {
	long double L = 0, R = 180, M, HIRITSU = y * 1.0L / V;
	for (int i = 0; i < 60; i++) {
		M = (L + R) / 2;
		long double F = cos(M * PI / 180.0L);
		if (F > HIRITSU) L = M;
		else R = M;
	}
	return M;
}

long double calc_angle(long double T) {
	long double E1 = 1.0L * V * V * T / 360.0L * PI;
	long double E2 = 0.5L * sin(T * PI / 180.0L) * V * V;
	return E1 - E2;
}

long double calc(long double X, long double H) {
	// 円は (0, 0) を中心としてよい
	long double Y1 = -sqrtl(V * V - X * X);
	long double Y2 = -sqrtl(V * V - (X + 1) * (X + 1));
	long double Y3 = sqrtl(V * V - (X + 1) * (X + 1));
	long double Y4 = sqrtl(V * V - X * X);

	long double rem = 0;
	if (H < Y1) {
		long double D1 = calc_kakudo(X, Y1);
		long double D2 = calc_kakudo(X + 1.0L, Y2);
		rem += 2.0L * calc_angle(abs(D1 - D2));

		vector<pair<long double, long double>>T;
		T.push_back(make_pair(X, Y1));
		T.push_back(make_pair(X + 1.0L, Y2));
		T.push_back(make_pair(X + 1.0L, Y3));
		T.push_back(make_pair(X, Y4));
		rem += calc_area(T);
	}
	else if (H < Y2) {
		long double FE = sqrtl(V * V - H * H);
		long double D1 = calc_kakudo(X, Y1);
		long double D2 = calc_kakudo(X + 1.0L, Y2);
		long double D3 = calc_kakudo(FE, H);
		rem += 1.0L * calc_angle(abs(D1 - D2));
		rem += 1.0L * calc_angle(abs(D2 - D3));

		vector<pair<long double, long double>>T;
		T.push_back(make_pair(X, H));
		T.push_back(make_pair(FE, H));
		T.push_back(make_pair(X + 1.0L, Y2));
		T.push_back(make_pair(X + 1.0L, Y3));
		T.push_back(make_pair(X, Y4));
		rem += calc_area(T);
	}
	else if (H < Y3) {
		long double D1 = calc_kakudo(X, Y1);
		long double D2 = calc_kakudo(X + 1.0L, Y2);
		rem += 1.0L * calc_angle(abs(D1 - D2));

		vector<pair<long double, long double>>T;
		T.push_back(make_pair(X, H));
		T.push_back(make_pair(X + 1.0L, H));
		T.push_back(make_pair(X + 1.0L, Y3));
		T.push_back(make_pair(X, Y4));
		rem += calc_area(T);
	}
	else if (H < Y4) {
		long double FE = sqrtl(V * V - H * H);
		long double D1 = calc_kakudo(X, Y4);
		long double D3 = calc_kakudo(FE, H);
		rem += 1.0L * calc_angle(abs(D1 - D3));

		vector<pair<long double, long double>>T;
		T.push_back(make_pair(X, H));
		T.push_back(make_pair(FE, H));
		T.push_back(make_pair(X, Y4));
		rem += calc_area(T);
	}
	else {
		rem = 0;
	}
	return rem;
}

long double solve(long double res) {
	long double ret = 0;
	for (int i = -V; i <= V - 1; i++) {
		ret += calc(min(abs(i), abs(i + 1)), 1.0L * E[100 + i] - res);
	}
	return ret;
}

int main() {
	cin >> N >> V;
	for (int i = 0; i < N; i++) {
		cin >> A[i] >> B[i] >> C[i];
		for (int j = A[i]; j < A[i] + B[i]; j++) E[100 + j] = max(E[100 + j], C[i]);
	}
	long double L = 0, R = 100, M, GOAL = 0.5L * V * V * PI;
	for (int i = 0; i < 100; i++) {
		M = (L + R) / 2;
		long double ss = solve(M);
		if (ss < GOAL) L = M;
		else R = M;
	}
	printf("%.12Lf\n", M);
	return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 3540
final_rank: 4

code_snippet: ////////////////////
// ???????????????
#include<cmath>
#include<algorithm>
#include<cassert>
////////////////////
// ??¨????????¢???
using D = double;
////////////////////
// ?????°
const D EPS = 1e-9;                // |EPS|???????????°???0??¨????????±???
enum POSITION {ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK};   // 3??????????????¢???
////////////////////
// ?§???????
struct Point {
  D x, y;
  Point(const D d = 0.0) : x(d), y(d) {}
  Point(const D x, const D y) : x(x), y(y) {}
};
struct Segment {
  Point initial, terminal;
  Segment(const Point& initial, const Point& terminal) : initial(initial), terminal(terminal) {}
  Segment(const D x1, const D y1, const D x2, const D y2) : initial(x1, y1), terminal(x2, y2) {}
};
struct Line {
  Point initial, terminal;
  Line(const Point& initial, const Point& terminal) : initial(initial), terminal(terminal) {}
  Line(const D x1, const D y1, const D x2, const D y2) : initial(x1, y1), terminal(x2, y2) {}
  Line(const Segment& s) : initial(s.initial), terminal(s.terminal) {}
};
////////////////////
// ????£?
bool relative_equal(const D d1, const D d2) {return d1 == 0 ? std::abs(d2) < EPS : std::abs((d1 - d2) / d1) < EPS;}
// ??????????????????????????????
bool operator==(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) && relative_equal(lhs.y, rhs.y);}
bool operator<(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) ? lhs.y < rhs.y : lhs.x < rhs.x;}
bool operator>(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) ? lhs.y > rhs.y : lhs.x > rhs.x;}
bool operator!=(const Point& lhs, const Point& rhs) {return !(lhs == rhs);}
bool operator<=(const Point& lhs, const Point& rhs) {return !(lhs > rhs);}
bool operator>=(const Point& lhs, const Point& rhs) {return !(lhs < rhs);}
const Point operator+(const Point& lhs, const Point& rhs) {return Point(lhs.x + rhs.x, lhs.y + rhs.y);}
const Point operator-(const Point& lhs, const Point& rhs) {return Point(lhs.x - rhs.x, lhs.y - rhs.y);}
const Point operator*(const Point& lhs, const Point& rhs) {return Point(lhs.x * rhs.x, lhs.y * rhs.y);}
const Point operator/(const Point& lhs, const Point& rhs) {return Point(lhs.x / rhs.x, lhs.y / rhs.y);}
const Point operator-(const Point& p) {return Point(-p.x, -p.y);}
// ???
D abs(const Point& p) {return std::hypot(p.x, p.y);}
D norm(const Point& p) {return p.x * p.x + p.y * p.y;}
D dot(const Point& a, const Point& b) {return a.x * b.x + a.y * b.y;}
D cross(const Point& a, const Point& b) {return a.x * b.y - a.y * b.x;}
// ??´???
bool parallel(const Line& l1, const Line& l2) {return relative_equal(0.0, cross(l2.terminal - l2.initial, l1.terminal - l1.initial));}
bool orthogonal(const Line& l1, const Line& l2) {return relative_equal(0.0, dot(l2.terminal - l2.initial, l1.terminal - l1.initial));}
// 3??????????????¢???
POSITION ccw(const Point& a, const Point& b, const Point& p) {
  Point v1 = b - a;
  Point v2 = p - a;
  if(cross(v1, v2) >= EPS) return COUNTER_CLOCKWISE;
  if(cross(v1, v2) <= -EPS) return CLOCKWISE;
  if(dot(v1, v2) <= -EPS) return ONLINE_BACK;
  if(norm(v1) < norm(v2)) return ONLINE_FRONT;              // ????????????: norm(v1)<norm(v2)+EPS?????¨WrongAnswer
  return ON_SEGMENT;
}
// ????????????
bool intersect(const Point& p1, const Point& p2) {return p1 == p2;}
bool intersect(const Point& p, const Segment& s) {return abs(p - s.initial) + abs(p - s.terminal) - abs(s.initial - s.terminal) <= EPS;}
bool intersect(const Segment& s, const Point& p) {return intersect(p, s);}
bool intersect(const Point& p, const Line& l) {return !parallel(Line(p, l.initial), Line(p, l.terminal));}
bool intersect(const Line& l, const Point& p) {return intersect(p, l);}
bool intersect(const Segment& s1, const Segment& s2) {
  return ccw(s1.initial, s1.terminal, s2.initial) * ccw(s1.initial, s1.terminal, s2.terminal) <= 0
      && ccw(s2.initial, s2.terminal, s1.initial) * ccw(s2.initial, s2.terminal, s1.terminal) <= 0;
}
bool intersect(const Segment& s, const Line& l) {
  auto v1 = l.terminal - l.initial;
  auto v2 = s.initial  - l.initial;
  auto v3 = s.terminal - l.initial;
  return cross(v1, v2) * cross(v1, v3) <= EPS;
}
bool intersect(const Line& l, const Segment& s) {return intersect(s, l);}
bool intersect(const Line& l1, const Line& l2) {return !parallel(l1, l2) || intersect(l1.initial, l2);}
// ???????§????
Point rotate(const Point& p, const D a) {return Point(p.x * std::cos(a) - p.y * std::sin(a), p.x * std::sin(a) + p.y * std::cos(a));}
Point projection(const Point& p, const Line& l) {
  auto v = l.initial - l.terminal;
  return l.initial + dot(p - l.initial, v) / norm(v) * v;
}
Point projection(const Line& l, const Point& p) {return projection(p, l);}
Point reflection(const Point& p, const Line& l) {return p + 2 * (projection(p, l) - p);}
Point reflection(const Line& l, const Point& p) {return reflection(p, l);}
// ?????¢
D distance(const Point& p1, const Point& p2) {
  auto p = p1 - p2;
  return hypot(p.x, p.y);
}
D distance(const Point& p, const Segment& s) {
  auto r = projection(s, p);
  return intersect(r, s) ? distance(p, r) : std::min(distance(p, s.initial), distance(p, s.terminal));
}
D distance(const Segment& s, const Point& p) {return distance(p, s);}
D distance(const Point& p, const Line& l) {return distance(p, projection(p, l));}
D distance(const Line& l, const Point& p) {return distance(p, l);}
D distance(const Segment& s1, const Segment& s2) {
  return intersect(s1, s2) ? 0.0 : std::min({distance(s1, s2.initial), distance(s1, s2.terminal), distance(s2, s1.initial), distance(s2, s1.terminal)});
}
D distance(const Segment& s, const Line& l) {return intersect(s, l) ? 0.0 : std::min(distance(s.initial, l), distance(s.terminal, l));}
D distance(const Line& l,const Segment& s) {return distance(s, l);}
D distance(const Line& l1, const Line& l2) {return intersect(l1, l2) ? 0.0 : distance(l1.initial, l2);}
// ??????
const Point crosspoint(const Line& l1, const Line& l2) {
  assert(intersect(l1, l2));
  if(parallel(l1, l2)) return l1.initial;                   // ???????????¨???l1????§?????????????
  D A = cross(l1.terminal - l1.initial, l2.terminal - l2.initial);
  D B = cross(l1.terminal - l1.initial, l1.terminal - l2.initial);
  return l2.initial + B / A * (l2.terminal - l2.initial);
}
const Point crosspoint(const Segment& s, const Line& l) {
  assert(intersect(s, l));
  if(parallel(s, l)) return s.initial;
  return crosspoint(Line(s), l);
}
const Point crosspoint(const Line& l, const Segment& s) {return crosspoint(s, l);}
const Point crosspoint(const Segment& s1, const Segment& s2) {
  assert(intersect(s1, s2));
  if(parallel(s1, s2)) {                                    // ???????????¨?????????????????????????????????
    if(intersect(s1.initial,  s2)) return s1.initial;
    if(intersect(s1.terminal, s2)) return s1.terminal;
    if(intersect(s2.initial,  s1)) return s2.initial;
    if(intersect(s2.terminal, s1)) return s2.terminal;
  }
  return crosspoint(Line(s1), Line(s2));
}
////////////////////////////////////////////////////////////////////////////////
// ???
#include<vector>
const D PI = std::acos(-1);
struct Circle {
  Point center;
  D radius;
  Circle(const Point& center = 0, const D radius = 0) : center(center), radius(radius) {}
  Circle(const D x, const D y, const D radius) : center(x, y), radius(radius) {}
};
D area(const Circle& c) {return PI * c.radius * c.radius;}
bool contain(const Circle& c, const Point& p) {
  D d = abs(p - c.center);
  if(relative_equal(c.radius, d)) return true;
  return d < c.radius;
}
bool contain(const Point& p, const Circle& c) {return contain(c, p);}
std::vector<Point> crosspoint(const Circle& c, const Line& l) {
  std::vector<Point> cp;
  Point p = projection(c.center, l);
  if(!contain(c, p)) return cp;
  Point v = p - c.center;
  if(relative_equal(abs(v), 0)) {
    Point p = l.initial - c.center;
    if(p == 0) p = l.terminal - c.center;
    p = (c.radius * p / abs(p));
    cp.push_back(c.center + p);
    cp.push_back(c.center - p);
    return cp;
  }
  D angle = acos(abs(v) / c.radius);
  for(D a: {angle, -angle}) cp.push_back(c.center + c.radius * (rotate(v, a) / abs(v)));
  return cp;
}
std::vector<Point> crosspoint(const Line& l, const Circle& c) {return crosspoint(c, l);}
int tangent(const Circle& c1, const Circle& c2) {
  D d = abs(c1.center - c2.center);
  D r = c1.radius + c2.radius;
  if(relative_equal(d, r)) return 3;    // ?????\
  if(r < d) return 4;                   // ?????¢
  r = std::abs(c1.radius - c2.radius);
  if(relative_equal(d, r)) return 1;    // ?????\
  if(r < d) return 2;                   // ??????
  return 0;                             // ??????
}

#include<bits/stdc++.h>
using namespace std;

int N;
D R;
vector<Point> P;

D triangle(const Point& a, const Point& b, const Point& c) {
  return abs(cross(b - a, c - a)) / 2.0;
}

D sector(const Circle& c, Point a, Point b) {
  a = a - c.center;
  b = b - c.center;
  auto angle = acos(dot(a, b) / abs(a) / abs(b));
  return c.radius * c.radius * angle / 2.0;
}

D area(const Circle& c, Point a, Point b) {
  if(a > b) swap(a, b);
  if(a == b || c.center == a || c.center == b) return 0;
  // ??????2????????????
  if(contain(c, a) && contain(c, b)) return triangle(c.center, a, b);
  auto cp = crosspoint(c, Line(a, b));
  // ????§???¢????????§?????????
  if(cp.empty()) return sector(c, a, b);
  if(cp[0] > cp[1]) swap(cp[0], cp[1]);
  // 2???????????????
  if(!contain(c, a) && !contain(c, b)) {
    if(b < cp[0] || cp[1] < a) return sector(c, a, b);
    else                       return sector(c, a, cp[0]) + triangle(c.center, cp[0], cp[1]) + sector(c, cp[1], b);
  }
  // 1?????????????????????
  if(contain(c, a)) return triangle(c.center, a, cp[1]) + sector(c, cp[1], b);
  else              return triangle(c.center, cp[0], b) + sector(c, a, cp[0]);
}

bool ok(D h) {
  D covered = 0;
  Circle c(0, h, R);
  for(auto i = 0; i < P.size(); ++i) {
    auto& cur = P[i], nex = P[(i + 1) % P.size()];
    auto rev = ccw(c.center, cur, nex) == COUNTER_CLOCKWISE;
    covered += area(c, cur, nex) * (rev ? -1 : 1);
  }
  return covered < area(c) / 2.0;
}

int main() {
  cin >> N >> R;

  D p = -200;
  P.emplace_back(p, -200);
  for(auto i = 0; i < N; ++i) {
    D x, w, h;
    cin >> x >> w >> h;
    if(p != x) P.emplace_back(p, 0);
    if(p != x) P.emplace_back(x, 0);
    P.emplace_back(x, h);
    P.emplace_back(x + w, h);
    p = x + w;
  }
  P.emplace_back(p, 0);
  P.emplace_back(200, 0);
  P.emplace_back(200, -200);

  const int LIMIT = 1e3;
  D low = -100, high = 200;
  for(auto step = 0; step < LIMIT; ++step) {
    auto middle = (low + high) / 2.0;
    if(ok(middle)) high = middle;
    else           low  = middle;
  }

  cout << setprecision(8) << fixed << low << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3648
final_rank: 1

code_snippet: ////////////////////
// ???????????????
#include<cmath>
#include<algorithm>
#include<cassert>
////////////////////
// ??¨????????¢???
using D = double;
////////////////////
// ?????°
const D EPS = 1e-9;                // |EPS|???????????°???0??¨????????±???
enum POSITION {ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK};   // 3??????????????¢???
////////////////////
// ?§???????
struct Point {
  D x, y;
  Point(const D d = 0.0) : x(d), y(d) {}
  Point(const D x, const D y) : x(x), y(y) {}
};
struct Segment {
  Point initial, terminal;
  Segment(const Point& initial, const Point& terminal) : initial(initial), terminal(terminal) {}
  Segment(const D x1, const D y1, const D x2, const D y2) : initial(x1, y1), terminal(x2, y2) {}
};
struct Line {
  Point initial, terminal;
  Line(const Point& initial, const Point& terminal) : initial(initial), terminal(terminal) {}
  Line(const D x1, const D y1, const D x2, const D y2) : initial(x1, y1), terminal(x2, y2) {}
  Line(const Segment& s) : initial(s.initial), terminal(s.terminal) {}
};
////////////////////
// ????£?
bool relative_equal(const D d1, const D d2) {return d1 == 0 ? std::abs(d2) < EPS : std::abs((d1 - d2) / d1) < EPS;}
// ??????????????????????????????
bool operator==(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) && relative_equal(lhs.y, rhs.y);}
bool operator<(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) ? lhs.y < rhs.y : lhs.x < rhs.x;}
bool operator>(const Point& lhs, const Point& rhs) {return relative_equal(lhs.x, rhs.x) ? lhs.y > rhs.y : lhs.x > rhs.x;}
bool operator!=(const Point& lhs, const Point& rhs) {return !(lhs == rhs);}
bool operator<=(const Point& lhs, const Point& rhs) {return !(lhs > rhs);}
bool operator>=(const Point& lhs, const Point& rhs) {return !(lhs < rhs);}
const Point operator+(const Point& lhs, const Point& rhs) {return Point(lhs.x + rhs.x, lhs.y + rhs.y);}
const Point operator-(const Point& lhs, const Point& rhs) {return Point(lhs.x - rhs.x, lhs.y - rhs.y);}
const Point operator*(const Point& lhs, const Point& rhs) {return Point(lhs.x * rhs.x, lhs.y * rhs.y);}
const Point operator/(const Point& lhs, const Point& rhs) {return Point(lhs.x / rhs.x, lhs.y / rhs.y);}
const Point operator-(const Point& p) {return Point(-p.x, -p.y);}
// ???
D abs(const Point& p) {return std::hypot(p.x, p.y);}
D norm(const Point& p) {return p.x * p.x + p.y * p.y;}
D dot(const Point& a, const Point& b) {return a.x * b.x + a.y * b.y;}
D cross(const Point& a, const Point& b) {return a.x * b.y - a.y * b.x;}
// ??´???
bool parallel(const Line& l1, const Line& l2) {return relative_equal(0.0, cross(l2.terminal - l2.initial, l1.terminal - l1.initial));}
bool orthogonal(const Line& l1, const Line& l2) {return relative_equal(0.0, dot(l2.terminal - l2.initial, l1.terminal - l1.initial));}
// 3??????????????¢???
POSITION ccw(const Point& a, const Point& b, const Point& p) {
  Point v1 = b - a;
  Point v2 = p - a;
  if(cross(v1, v2) >= EPS) return COUNTER_CLOCKWISE;
  if(cross(v1, v2) <= -EPS) return CLOCKWISE;
  if(dot(v1, v2) <= -EPS) return ONLINE_BACK;
  if(norm(v1) < norm(v2)) return ONLINE_FRONT;              // ????????????: norm(v1)<norm(v2)+EPS?????¨WrongAnswer
  return ON_SEGMENT;
}
// ????????????
bool intersect(const Point& p1, const Point& p2) {return p1 == p2;}
bool intersect(const Point& p, const Segment& s) {return abs(p - s.initial) + abs(p - s.terminal) - abs(s.initial - s.terminal) <= EPS;}
bool intersect(const Segment& s, const Point& p) {return intersect(p, s);}
bool intersect(const Point& p, const Line& l) {return !parallel(Line(p, l.initial), Line(p, l.terminal));}
bool intersect(const Line& l, const Point& p) {return intersect(p, l);}
bool intersect(const Segment& s1, const Segment& s2) {
  return ccw(s1.initial, s1.terminal, s2.initial) * ccw(s1.initial, s1.terminal, s2.terminal) <= 0
      && ccw(s2.initial, s2.terminal, s1.initial) * ccw(s2.initial, s2.terminal, s1.terminal) <= 0;
}
bool intersect(const Segment& s, const Line& l) {
  auto v1 = l.terminal - l.initial;
  auto v2 = s.initial  - l.initial;
  auto v3 = s.terminal - l.initial;
  return cross(v1, v2) * cross(v1, v3) <= EPS;
}
bool intersect(const Line& l, const Segment& s) {return intersect(s, l);}
bool intersect(const Line& l1, const Line& l2) {return !parallel(l1, l2) || intersect(l1.initial, l2);}
// ???????§????
Point rotate(const Point& p, const D a) {return Point(p.x * std::cos(a) - p.y * std::sin(a), p.x * std::sin(a) + p.y * std::cos(a));}
Point projection(const Point& p, const Line& l) {
  auto v = l.initial - l.terminal;
  return l.initial + dot(p - l.initial, v) / norm(v) * v;
}
Point projection(const Line& l, const Point& p) {return projection(p, l);}
Point reflection(const Point& p, const Line& l) {return p + 2 * (projection(p, l) - p);}
Point reflection(const Line& l, const Point& p) {return reflection(p, l);}
// ?????¢
D distance(const Point& p1, const Point& p2) {
  auto p = p1 - p2;
  return hypot(p.x, p.y);
}
D distance(const Point& p, const Segment& s) {
  auto r = projection(s, p);
  return intersect(r, s) ? distance(p, r) : std::min(distance(p, s.initial), distance(p, s.terminal));
}
D distance(const Segment& s, const Point& p) {return distance(p, s);}
D distance(const Point& p, const Line& l) {return distance(p, projection(p, l));}
D distance(const Line& l, const Point& p) {return distance(p, l);}
D distance(const Segment& s1, const Segment& s2) {
  return intersect(s1, s2) ? 0.0 : std::min({distance(s1, s2.initial), distance(s1, s2.terminal), distance(s2, s1.initial), distance(s2, s1.terminal)});
}
D distance(const Segment& s, const Line& l) {return intersect(s, l) ? 0.0 : std::min(distance(s.initial, l), distance(s.terminal, l));}
D distance(const Line& l,const Segment& s) {return distance(s, l);}
D distance(const Line& l1, const Line& l2) {return intersect(l1, l2) ? 0.0 : distance(l1.initial, l2);}
// ??????
const Point crosspoint(const Line& l1, const Line& l2) {
  assert(intersect(l1, l2));
  if(parallel(l1, l2)) return l1.initial;                   // ???????????¨???l1????§?????????????
  D A = cross(l1.terminal - l1.initial, l2.terminal - l2.initial);
  D B = cross(l1.terminal - l1.initial, l1.terminal - l2.initial);
  return l2.initial + B / A * (l2.terminal - l2.initial);
}
const Point crosspoint(const Segment& s, const Line& l) {
  assert(intersect(s, l));
  if(parallel(s, l)) return s.initial;
  return crosspoint(Line(s), l);
}
const Point crosspoint(const Line& l, const Segment& s) {return crosspoint(s, l);}
const Point crosspoint(const Segment& s1, const Segment& s2) {
  assert(intersect(s1, s2));
  if(parallel(s1, s2)) {                                    // ???????????¨?????????????????????????????????
    if(intersect(s1.initial,  s2)) return s1.initial;
    if(intersect(s1.terminal, s2)) return s1.terminal;
    if(intersect(s2.initial,  s1)) return s2.initial;
    if(intersect(s2.terminal, s1)) return s2.terminal;
  }
  return crosspoint(Line(s1), Line(s2));
}
////////////////////////////////////////////////////////////////////////////////
// ?????????
#include<vector>
const D PI = std::acos(-1);
struct Circle {
  Point center;
  D radius;
  Circle(const Point& center = 0, const D radius = 0) : center(center), radius(radius) {}
  Circle(const D x, const D y, const D radius) : center(x, y), radius(radius) {}
};
D area(const Circle& c) {return PI * c.radius * c.radius;}
bool contain(const Circle& c, const Point& p) {
  D d = abs(p - c.center);
  if(relative_equal(c.radius, d)) return true;
  return d < c.radius;
}
bool contain(const Point& p, const Circle& c) {return contain(c, p);}
#include<bits/stdc++.h>
using namespace std;
std::vector<Point> crosspoint(const Circle& c, const Line& l) {
  std::vector<Point> cp;
  Point p = projection(c.center, l);
  if(!contain(c, p)) return cp;
  Point v = p - c.center;
  if(relative_equal(abs(v), 0)) {
    Point p = l.initial - c.center;
    if(p == 0) p = l.terminal - c.center;
    p = (c.radius * p / abs(p));
    cp.push_back(c.center + p);
    cp.push_back(c.center - p);
    return cp;
  }
  D angle = acos(abs(v) / c.radius);
  for(D a: {angle, -angle}) cp.push_back(c.center + c.radius * (rotate(v, a) / abs(v)));
  return cp;
}
std::vector<Point> crosspoint(const Line& l, const Circle& c) {return crosspoint(c, l);}
int tangent(const Circle& c1, const Circle& c2) {
  D d = abs(c1.center - c2.center);
  D r = c1.radius + c2.radius;
  if(relative_equal(d, r)) return 3;    // ?????\
  if(r < d) return 4;                   // ?????¢
  r = std::abs(c1.radius - c2.radius);
  if(relative_equal(d, r)) return 1;    // ?????\
  if(r < d) return 2;                   // ??????
  return 0;                             // ??????
}

#include<bits/stdc++.h>
using namespace std;

int N;
D R;
vector<Point> P;

D triangle(const Point& a, const Point& b, const Point& c) {
  return abs(cross(b - a, c - a)) / 2.0;
}

D sector(const Circle& c, Point a, Point b) {
  a = a - c.center;
  b = b - c.center;
  auto angle = acos(dot(a, b) / abs(a) / abs(b));
  return c.radius * c.radius * angle / 2.0;
//   auto a1 = atan2(a.y - c.center.y, a.x - c.center.x);
//   auto a2 = atan2(b.y - c.center.y, b.x - c.center.x);
//   auto angle = a2 - a1;
//   cout<<a1<<"    "<<a2<<endl;
//   cout<<angle<<endl;
//   return c.radius * c.radius * angle / 2.0;
}

D area(const Circle& c, Point a, Point b) {
  if(a > b) swap(a, b);
  if(a == b || c.center == a || c.center == b) return 0;
  // ??????2????????????
  if(contain(c, a) && contain(c, b)) return triangle(c.center, a, b);
  auto cp = crosspoint(c, Line(a, b));
  // ????§???¢????????§?????????
  if(cp.empty()) return sector(c, a, b);
  if(cp[0] > cp[1]) swap(cp[0], cp[1]);
  // 2???????????????
  if(!contain(c, a) && !contain(c, b)) {
    if(b < cp[0] || cp[1] < a) return sector(c, a, b);
    else                       return sector(c, a, cp[0]) + triangle(c.center, cp[0], cp[1]) + sector(c, cp[1], b);
  }
  // 1?????????????????????
  if(contain(c, a)) return triangle(c.center, a, cp[1]) + sector(c, cp[1], b);
  else              return triangle(c.center, cp[0], b) + sector(c, a, cp[0]);
}

bool ok(D h) {
  D covered = 0;
  Circle c(0, h, R);
  for(auto i = 0; i < P.size(); ++i) {
    auto& cur = P[i], nex = P[(i + 1) % P.size()];
    auto rev = ccw(c.center, cur, nex) == COUNTER_CLOCKWISE;
    covered += area(c, cur, nex) * (rev ? -1 : 1);
  }
  return covered < area(c) / 2.0;
}

int main() {
  cin >> N >> R;

  D p = -200;
  P.emplace_back(p, -200);
  for(auto i = 0; i < N; ++i) {
    D x, w, h;
    cin >> x >> w >> h;
    if(p != x) P.emplace_back(p, 0);
    if(p != x) P.emplace_back(x, 0);
    P.emplace_back(x, h);
    P.emplace_back(x + w, h);
    p = x + w;
  }
  P.emplace_back(p, 0);
  P.emplace_back(200, 0);
  P.emplace_back(200, -200);

  const int LIMIT = 1e4;
  D low = -100, high = 200;
  for(auto step = 0; step < LIMIT; ++step) {
    auto middle = (low + high) / 2.0;
    if(ok(middle)) high = middle;
    else           low  = middle;
  }

  cout << setprecision(8) << fixed << low << endl;
}
accuracy: 1
time_ms: 230
memory_kb: 3660
final_rank: 3