작성일 :

문제 링크

2022번 - 사다리

설명

길이 x, y인 두 사다리가 서로 건너편 건물에 기대고, 지면 위 c 높이에서 교차합니다.

두 건물 사이의 너비 w를 구하는 문제입니다.


접근법

먼저, 너비 w가 주어지면 각 사다리가 닿는 건물 높이를 계산할 수 있습니다. 피타고라스 정리로 첫 번째 건물 높이는 x 제곱에서 w 제곱을 뺀 값의 제곱근이고, 두 번째 건물 높이도 마찬가지입니다.

다음으로, 두 사다리가 교차하는 높이는 닮은 삼각형의 성질을 이용하면 두 건물 높이의 곱을 두 건물 높이의 합으로 나눈 값이 됩니다. 예를 들어, 첫 번째 건물 높이가 4이고 두 번째 건물 높이가 6이면 교차 높이는 4 곱하기 6을 4 더하기 6으로 나눈 2.4가 됩니다.

이후, 교차 높이가 c가 되는 w를 찾습니다. w가 커지면 건물 높이가 낮아지므로 교차 높이도 낮아집니다. 이 단조성을 이용해 이분 탐색으로 w를 찾습니다.

w의 범위는 0부터 x와 y 중 작은 값까지입니다.



Code

C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;

namespace Solution {
  class Program {
    static double x, y, c;

    static double Height(double w) {
      var h1 = Math.Sqrt(x * x - w * w);
      var h2 = Math.Sqrt(y * y - w * w);
      return (h1 * h2) / (h1 + h2);
    }

    static void Main(string[] args) {
      var parts = Console.ReadLine()!.Split();
      x = double.Parse(parts[0]);
      y = double.Parse(parts[1]);
      c = double.Parse(parts[2]);

      var low = 0.0;
      var high = Math.Min(x, y);
      var ans = 0.0;
      while (high - low > 1e-6) {
        var mid = (low + high) / 2.0;
        if (Height(mid) >= c) {
          ans = mid;
          low = mid;
        } else high = mid;
      }

      Console.WriteLine(ans.ToString("0.000"));
    }
  }
}

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
using namespace std;

double x, y, c;

double height(double w) {
  double h1 = sqrt(x * x - w * w);
  double h2 = sqrt(y * y - w * w);
  return (h1 * h2) / (h1 + h2);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  cin >> x >> y >> c;
  double low = 0, high = min(x, y), ans = 0;
  while (high - low > 1e-6) {
    double mid = (low + high) / 2.0;
    if (height(mid) >= c) {
      ans = mid;
      low = mid;
    } else high = mid;
  }

  cout << fixed << setprecision(3) << ans << "\n";

  return 0;
}