배달 드론이 기지 (0, 0, 0)에서 떠나 배달할 곳 n군데를 주어진 차례대로 들른 뒤 기지로 돌아온다.
첫 줄에 배달할 곳의 수 n이 주어진다.
다음 n줄에는 들르는 차례대로 배달할 곳의 좌표 x, y, z(센티미터)가 빈칸으로 띄워 한 줄에 하나씩 주어진다.
드론은 한 곳에서 다음 곳까지 곧게 날아간다.
두 곳 사이의 거리는 x, y, z 차이를 각각 제곱해 더한 값의 제곱근이다.
구간은 n + 1개다: 1번 구간은 기지에서 첫 곳까지, k번 구간은 (k-1)째 곳에서 k째 곳까지, n + 1번 구간은 n째 곳에서 기지까지다.
같은 곳이 이어서 나오거나 기지와 같은 곳이 나올 수도 있고, 그러면 그 구간의 거리는 0이다.
1번 구간부터 n + 1번 구간까지, 구간을 하나 날 때마다 그때까지 날아간 거리의 합을 한 줄에 출력하라.
거리의 합은 소수 둘째 자리까지 반올림해 소수점 아래를 정확히 두 자리로 쓴다(5는 5.00).
반올림이 헷갈리지 않도록, 출력할 모든 합은 100을 곱했을 때 소수 부분이 0.4 이상 0.6 이하가 되지 않게 주어진다.
마지막 줄에는 가장 긴 구간의 번호를 출력하라.
가장 긴 구간이 여럿이면 그중 번호가 가장 작은 것을 출력한다.
입력
1 ≤ n ≤ 1,000, -1,000,000 ≤ x, y ≤ 1,000,000, 0 ≤ z ≤ 100,000(모두 정수), 출력할 합 × 100의 소수 부분이 0.4~0.6인 입력은 없다
출력
n + 1줄: 구간마다 그때까지의 거리 합(소수 둘째 자리까지) / 마지막 줄: 가장 긴 구간의 번호
예시 1 · stdin
2
3 4 0
3 4 12
stdout
5.00
17.00
30.00
3
예시 2 · stdin
4
2 0 0
2 0 0
5 0 0
5 4 0
stdout
2.00
2.00
5.00
9.00
15.40
5
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
제곱근은 Python math.sqrt(또는 ** 0.5), JS·TS Math.sqrt, Java Math.sqrt, C# Math.Sqrt, C sqrt(<math.h>, 링크할 때 -lm), C++ std::sqrt(<cmath>), 크레이콘 수학.제곱근이에요. 모두 double을 돌려주니 long len = sqrt(...)처럼 정수 변수에 담으면 5.83이 5가 돼요. 제곱하기 전의 크기를 먼저 봐야 해요. 좌표 차이는 2×10^6까지라 제곱하면 4×10^12이고, 32비트 int는 차이가 46,341 이상이기만 해도 제곱이 넘쳐요. Java·C#은 좌표를 long으로, C·C++은 long long으로 읽어서 곱해요. Python 정수는 크기 제한이 없고, JS·TS·크레이콘의 수는 2^53까지 정수가 정확해서 세 제곱의 합(약 8×10^12)도 그대로 맞아요. 합은 C float이나 C# float로 쌓으면 유효숫자가 일곱 자리쯤이라 수십억 센티미터에서 소수 자리가 틀려요. double을 써요. 출력은 Python f"{total:.2f}", JS·TS toFixed(2), Java String.format(Locale.ROOT, "%.2f", total), C# ToString("F2", CultureInfo.InvariantCulture), C·C++ printf("%.2f"), 크레이콘 글자.소수자리맞추기(total, 2)예요. Math.floor(total * 100) / 100처럼 내리면 반올림이 아니라 버림이 돼요. 가장 긴 구간은 제곱근을 구하지 않고 정수인 제곱의 합끼리 비교해도 되고, 그러면 실수 오차를 생각할 필요가 없어요. >로 비교해야 같은 길이일 때 앞 번호가 남아요. 기지로 돌아오는 n + 1번 구간을 빠뜨리지 않게, 좌표 목록 끝에 (0, 0, 0)을 하나 더 붙이면 반복 하나로 끝나요.
Pythonmain.py · 18 줄
import mathn = int(input())points = [tuple(map(int, input().split())) for _ in range(n)]points.append((0, 0, 0)) # 마지막 구간은 기지로 돌아오는 길cur = (0, 0, 0)total = 0.0best, best_sq = 1, -1for i, p in enumerate(points, start=1): dx, dy, dz = p[0] - cur[0], p[1] - cur[1], p[2] - cur[2] sq = dx * dx + dy * dy + dz * dz # 정수 그대로 비교한다 total += math.sqrt(sq) print(f"{total:.2f}") if sq > best_sq: best, best_sq = i, sq cur = pprint(best)
JavaScriptmain.js · 26 줄
const nums = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const n = nums[0];const points = [];for (let i = 0; i < n; i++) points.push(nums.slice(1 + 3 * i, 4 + 3 * i));points.push([0, 0, 0]); // 마지막 구간은 기지로 돌아오는 길let cur = [0, 0, 0];let total = 0;let best = 1;let bestSq = -1;const out = [];points.forEach((p, i) => { const dx = p[0] - cur[0]; const dy = p[1] - cur[1]; const dz = p[2] - cur[2]; const sq = dx * dx + dy * dy + dz * dz; // 최대 약 8×10^12: 2^53 안이라 정확하다 total += Math.sqrt(sq); out.push(total.toFixed(2)); if (sq > bestSq) { best = i + 1; bestSq = sq; } cur = p;});out.push(best);console.log(out.join("\n"));
TypeScriptmain.ts · 28 줄
import { readFileSync } from "node:fs";const nums: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const n = nums[0];type Point = [number, number, number];const points: Point[] = [];for (let i = 0; i < n; i++) points.push([nums[1 + 3 * i], nums[2 + 3 * i], nums[3 + 3 * i]]);points.push([0, 0, 0]); // 마지막 구간은 기지로 돌아오는 길let cur: Point = [0, 0, 0];let total = 0;let best = 1;let bestSq = -1;const out: string[] = [];points.forEach((p, i) => { const dx = p[0] - cur[0]; const dy = p[1] - cur[1]; const dz = p[2] - cur[2]; const sq = dx * dx + dy * dy + dz * dz; // 최대 약 8×10^12: 2^53 안이라 정확하다 total += Math.sqrt(sq); out.push(total.toFixed(2)); if (sq > bestSq) { best = i + 1; bestSq = sq; } cur = p;});out.push(String(best));console.log(out.join("\n"));
JavaMain.java · 36 줄
import java.util.Locale;import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); long cx = 0, cy = 0, cz = 0; double total = 0; int best = 1; long bestSq = -1; StringBuilder out = new StringBuilder(); for (int i = 1; i <= n + 1; i++) { // 마지막(n + 1번째) 구간은 기지 (0, 0, 0)으로 돌아오는 길 long x = 0, y = 0, z = 0; if (i <= n) { x = sc.nextLong(); y = sc.nextLong(); z = sc.nextLong(); } long dx = x - cx, dy = y - cy, dz = z - cz; long sq = dx * dx + dy * dy + dz * dz; // 차이가 2×10^6이면 제곱은 4×10^12: long이 필요하다 total += Math.sqrt(sq); out.append(String.format(Locale.ROOT, "%.2f", total)).append('\n'); if (sq > bestSq) { best = i; bestSq = sq; } cx = x; cy = y; cz = z; } out.append(best).append('\n'); System.out.print(out); }}
C#Main.cs · 42 줄
using System;using System.Globalization;using System.Text;class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); long cx = 0, cy = 0, cz = 0; double total = 0; int best = 1; long bestSq = -1; var out_ = new StringBuilder(); for (int i = 1; i <= n + 1; i++) { // 마지막(n + 1번째) 구간은 기지 (0, 0, 0)으로 돌아오는 길 long x = 0, y = 0, z = 0; if (i <= n) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); x = long.Parse(p[0]); y = long.Parse(p[1]); z = long.Parse(p[2]); } long dx = x - cx, dy = y - cy, dz = z - cz; long sq = dx * dx + dy * dy + dz * dz; // 차이가 2×10^6이면 제곱은 4×10^12: long이 필요하다 total += Math.Sqrt(sq); out_.Append(total.ToString("F2", CultureInfo.InvariantCulture)).Append('\n'); if (sq > bestSq) { best = i; bestSq = sq; } cx = x; cy = y; cz = z; } out_.Append(best).Append('\n'); Console.Write(out_); }}
C++main.cpp · 29 줄
#include <cmath>#include <cstdio>#include <iostream>int main() { int n; std::cin >> n; long long cx = 0, cy = 0, cz = 0; double total = 0; int best = 1; long long bestSq = -1; for (int i = 1; i <= n + 1; i++) { // 마지막(n + 1번째) 구간은 기지 (0, 0, 0)으로 돌아오는 길 long long x = 0, y = 0, z = 0; if (i <= n) std::cin >> x >> y >> z; long long dx = x - cx, dy = y - cy, dz = z - cz; long long sq = dx * dx + dy * dy + dz * dz; // 제곱은 4×10^12까지: long long total += std::sqrt(static_cast<double>(sq)); std::printf("%.2f\n", total); if (sq > bestSq) { best = i; bestSq = sq; } cx = x; cy = y; cz = z; } std::printf("%d\n", best);}
Cmain.c · 29 줄
#include <math.h>#include <stdio.h>int main(void) { int n; scanf("%d", &n); long long cx = 0, cy = 0, cz = 0; double total = 0; /* float는 일곱 자리쯤에서 끝나 소수 둘째 자리를 지킬 수 없다 */ int best = 1; long long best_sq = -1; for (int i = 1; i <= n + 1; i++) { /* 마지막(n + 1번째) 구간은 기지 (0, 0, 0)으로 돌아오는 길 */ long long x = 0, y = 0, z = 0; if (i <= n) scanf("%lld %lld %lld", &x, &y, &z); long long dx = x - cx, dy = y - cy, dz = z - cz; long long sq = dx * dx + dy * dy + dz * dz; /* 제곱은 4×10^12까지: long long */ total += sqrt((double)sq); printf("%.2f\n", total); if (sq > best_sq) { best = i; best_sq = sq; } cx = x; cy = y; cz = z; } printf("%d\n", best); return 0;}
Craykonmain.cray · 31 줄
n = 콘솔.줄읽기().수로변환();cx = 0;cy = 0;cz = 0;total = 0;best = 1;bestSq = -1;반복 (i = 1; i <= n + 1; i++){ // 마지막(n + 1번째) 구간은 기지 (0, 0, 0)으로 돌아오는 길 p = [0, 0, 0]; 만약 (i <= n) { p = 콘솔.수들읽기(); } dx = p[0] - cx; dy = p[1] - cy; dz = p[2] - cz; sq = dx * dx + dy * dy + dz * dz; // 최대 약 8×10^12: 2^53 안이라 정확하다 total += 수학.제곱근(sq); 콘솔.쓰기(글자.소수자리맞추기(total, 2)); 만약 (sq > bestSq) { best = i; bestSq = sq; } cx = p[0]; cy = p[1]; cz = p[2];}콘솔.쓰기(best);