작성일 :

문제 링크

1069번 - 집으로

설명

현재 위치에서 원점까지 이동하는 최소 시간을 구하는 문제입니다. 걷기는 1초에 1만큼 이동하고, 점프는 T초에 정확히 D만큼 이동합니다.


접근법

먼저, 원점까지의 직선 거리를 구합니다. 점프 속도가 걷기보다 느리거나 같으면 걷기만 하는 것이 최선이므로 거리를 그대로 출력합니다.

다음으로, 점프가 더 빠른 경우 여러 후보를 비교합니다. 거리를 D로 나눈 몫 k번 점프 후 남은 거리를 걷는 경우와, k+1번 점프하여 약간 지나치는 경우를 비교합니다.

이후, k가 0인 경우 특별히 처리합니다. 한 번 점프 후 뒤로 걷는 경우와, 두 번 점프하여 제자리로 돌아오는 경우를 추가로 비교합니다. 예를 들어, 거리가 3이고 D가 5이면 한 번 점프 후 2만큼 뒤로 걷거나, 두 번 점프하여 정확히 도착할 수 있습니다.

모든 후보 중 최소값이 답이 됩니다.



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
using System;

namespace Solution {
  class Program {
    static void Main(string[] args) {
      var parts = Console.ReadLine()!.Split();
      var x = double.Parse(parts[0]);
      var y = double.Parse(parts[1]);
      var d = double.Parse(parts[2]);
      var t = double.Parse(parts[3]);

      var dist = Math.Sqrt(x * x + y * y);
      var ans = dist;

      if (d > t) {
        var k = (long)(dist / d);
        var remain = dist - k * d;
        if (k == 0) {
          ans = Math.Min(ans, Math.Min(t + (d - dist), 2.0 * t));
        } else {
          ans = Math.Min(ans, k * t + remain);
          ans = Math.Min(ans, (k + 1) * t);
        }
      }

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

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
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

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

  double x, y, d, t; cin >> x >> y >> d >> t;

  double dist = hypot(x, y);
  double ans = dist;

  if (d <= t) {
    cout << fixed << setprecision(9) << ans << "\n";
    return 0;
  }

  ll k = (ll)(dist / d);
  double remain = dist - k * d;

  if (k == 0) {
    ans = min(ans, min(t + (d - dist), 2.0 * t));
  } else {
    ans = min(ans, k * t + remain);
    ans = min(ans, (k + 1) * t);
  }

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

  return 0;
}