終わりの印(番兵)まで回るループは「読む、印かどうか聞く、処理する、また読む」の順を守る必要があります。 C while (scanf("%d", &x) == 1 && x != 0)、C++ while (std::cin >> x && x != 0)、Java while ((x = sc.nextInt()) != 0)、C# while ((x = int.Parse(Console.ReadLine())) != 0) は読むことと聞くことを条件一行に入れます。 Python は while True: で回り、読んだ後 if x == 0: break で抜けます。 JS・TS は入力全体を行に分けて for (const line of lines) で回り、0 で break します。 Craykon はループの前で一回読み、間 (x != 0) の中のいちばん最後でまた読みます。 do { 読んで処理 } while (x != 0) のように処理を先にすると、終わりの印 0 まで階として扱い、エレベーターがない 0 階へ行ってしまいます。 入力の終わりまで読みながら 0 だけを飛ばすのも間違いです。 0 の後に残った行まで処理してしまいます。 Craykon コンソール.行読み() は文字列 "0" を返し、"0" と数の 0 は等しくないので、数に() をせずに 0 と比べると印を通り過ぎて入力の終わりの なし で止まります。 同じ階の要求は、Python・JS・TS・Java・C#・C・C++ では continue で飛ばせば済みます。 読むことがループの条件の中かループの先頭にあるので、次の行が読まれるからです。 Craykon のように、また読む行がループのいちばん最後にあると、次へ がその行まで飛ばしてしまい、同じ値で回り続け、「時間がかかりすぎます」のエラーで止まります。 そこで Craykon の解答は もし (target != floor) の中に処理を入れ、また読む行はそのブロックの外に置きます。 距離は Python abs、JS・TS・Java Math.abs、C# Math.Abs、C abs(<stdlib.h>)、C++ std::abs(<cstdlib>)、Craykon 数学.絶対値 で求め、二つの階の符号が違えば(一方が地上、一方が地下)ない 0 階の分として 1 を引きます。 向きは「すぐ前の動き」と比べるので、同じ階の要求で覚えている向きを消してはいけません。
Pythonmain.py · 20 行
floor = 1stops = distance = turns = 0last_dir = 0 # 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음while True: target = int(input()) if target == 0: # 끝 표시: 0 뒤의 줄은 읽지 않는다 break if target == floor: continue # 같은 층: 정차도 아니고 방향도 그대로 gap = abs(target - floor) if (floor > 0) != (target > 0): gap -= 1 # 지상과 지하 사이에는 0층이 없다 d = 1 if target > floor else -1 if last_dir != 0 and d != last_dir: turns += 1 stops += 1 distance += gap last_dir = d floor = targetprint(stops, distance, turns)
JavaScriptmain.js · 20 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");let floor = 1;let stops = 0;let distance = 0;let turns = 0;let lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음for (const line of lines) { const target = Number(line); if (target === 0) break; // 끝 표시: 뒤의 줄은 보지 않는다 if (target === floor) continue; // 같은 층: 정차도 아니고 방향도 그대로 let gap = Math.abs(target - floor); if (floor > 0 !== target > 0) gap -= 1; // 지상과 지하 사이에는 0층이 없다 const d = target > floor ? 1 : -1; if (lastDir !== 0 && d !== lastDir) turns++; stops++; distance += gap; lastDir = d; floor = target;}console.log(`${stops} ${distance} ${turns}`);
TypeScriptmain.ts · 21 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");let floor = 1;let stops = 0;let distance = 0;let turns = 0;let lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음for (const line of lines) { const target = Number(line); if (target === 0) break; // 끝 표시: 뒤의 줄은 보지 않는다 if (target === floor) continue; // 같은 층: 정차도 아니고 방향도 그대로 let gap = Math.abs(target - floor); if (floor > 0 !== target > 0) gap -= 1; // 지상과 지하 사이에는 0층이 없다 const d = target > floor ? 1 : -1; if (lastDir !== 0 && d !== lastDir) turns++; stops++; distance += gap; lastDir = d; floor = target;}console.log(`${stops} ${distance} ${turns}`);
JavaMain.java · 23 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int floor = 1, stops = 0, distance = 0, turns = 0; int lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음 int target; // 끝 표시 0이 나오면 멈춘다: 0 뒤의 줄은 읽지 않는다 while ((target = sc.nextInt()) != 0) { if (target == floor) continue; // 같은 층: 정차도 아니고 방향도 그대로 int gap = Math.abs(target - floor); if ((floor > 0) != (target > 0)) gap--; // 지상과 지하 사이에는 0층이 없다 int d = target > floor ? 1 : -1; if (lastDir != 0 && d != lastDir) turns++; stops++; distance += gap; lastDir = d; floor = target; } System.out.println(stops + " " + distance + " " + turns); }}
C#Main.cs · 25 行
using System;class Program{ static void Main() { int floor = 1, stops = 0, distance = 0, turns = 0; int lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음 int target; // 끝 표시 0이 나오면 멈춘다: 0 뒤의 줄은 읽지 않는다 while ((target = int.Parse(Console.ReadLine())) != 0) { if (target == floor) continue; // 같은 층: 정차도 아니고 방향도 그대로 int gap = Math.Abs(target - floor); if ((floor > 0) != (target > 0)) gap--; // 지상과 지하 사이에는 0층이 없다 int d = target > floor ? 1 : -1; if (lastDir != 0 && d != lastDir) turns++; stops++; distance += gap; lastDir = d; floor = target; } Console.WriteLine($"{stops} {distance} {turns}"); }}
C++main.cpp · 21 行
#include <cstdlib>#include <iostream>int main() { int floor = 1, stops = 0, distance = 0, turns = 0; int lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음 int target; // 끝 표시 0이 나오면 멈춘다: 0 뒤의 줄은 읽지 않는다 while (std::cin >> target && target != 0) { if (target == floor) continue; // 같은 층: 정차도 아니고 방향도 그대로 int gap = std::abs(target - floor); if ((floor > 0) != (target > 0)) gap--; // 지상과 지하 사이에는 0층이 없다 int d = target > floor ? 1 : -1; if (lastDir != 0 && d != lastDir) turns++; stops++; distance += gap; lastDir = d; floor = target; } std::cout << stops << ' ' << distance << ' ' << turns << '\n';}
Cmain.c · 22 行
#include <stdio.h>#include <stdlib.h>int main(void) { int floor = 1, stops = 0, distance = 0, turns = 0; int last_dir = 0; /* 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음 */ int target; /* 끝 표시 0이 나오면 멈춘다: 0 뒤의 줄은 읽지 않는다 */ while (scanf("%d", &target) == 1 && target != 0) { if (target == floor) continue; /* 같은 층: 정차도 아니고 방향도 그대로 */ int gap = abs(target - floor); if ((floor > 0) != (target > 0)) gap--; /* 지상과 지하 사이에는 0층이 없다 */ int d = target > floor ? 1 : -1; if (last_dir != 0 && d != last_dir) turns++; stops++; distance += gap; last_dir = d; floor = target; } printf("%d %d %d\n", stops, distance, turns); return 0;}
Craykonmain.cray · 33 行
floor = 1;stops = 0;distance = 0;turns = 0;lastDir = 0; // 1이면 올라감, -1이면 내려감, 0이면 아직 움직이지 않음target = コンソール.行読み().数に();// 끝 표시 0이 나오면 멈춘다: 0 뒤의 줄은 읽지 않는다間 (target != 0){ もし (target != floor) { gap = 数学.絶対値(target - floor); もし (floor > 0 != target > 0) { gap--; // 지상과 지하 사이에는 0층이 없다 } d = -1; もし (target > floor) { d = 1; } もし (lastDir != 0 && d != lastDir) { turns++; } stops++; distance += gap; lastDir = d; floor = target; } target = コンソール.行読み().数に();}コンソール.書く(stops + " " + distance + " " + turns);