循环到结束标记(哨兵)为止时,要守住“读入、问是不是结束标记、处理、再读入”的顺序。 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);