用字符画一把尺子并输出。 第一行给出尺子长度 n 和大刻度间隔 k,用一个空格隔开。 尺子有从 0 到 n 共 n + 1 格,格号从左起为 0, 1, 2, …, n。 第一行输出是刻度行。 恰好 n + 1 个字符,第 c 格的字符在 c 是 k 的倍数时为 |,否则为 .。 第二行是数字行。 按从小到大的顺序看 n 以下的 k 的倍数 m = 0, k, 2k, 3k, …,尝试把 m 的十进制从第 m 格开始向右写。 写下 m 时占用的最后一格是 m + (m 的位数)− 1。 若这一格大于 n,就不写 m。 另外,如果已经写过数字,那个数字的最后一格与第 m 格之间必须至少有一个空格。 否则不写 m。 跳过没写的数字对之后的判断没有任何影响。 没写数字的格是空格,数字行末尾的空格不输出。 第三行输出数字行上写了几个数字。
输入
1 ≤ k ≤ n ≤ 5000
输出
三行
样例 1 · stdin
25 5
stdout
|....|....|....|....|....|
0 5 10 15 20
5
样例 2 · stdin
12 1
stdout
|||||||||||||
0 2 4 6 8 10
6
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
刻度是每次跳 k 的循环。 Python 的 range(0, n + 1, k) 不包含终点,所以要给到 n + 1 才包含第 n 格。 其他语言用 for (m = 0; m <= n; m += k),Craykon 用 循环 (m = 0; m <= n; m += k)。 刻度行若用 c < n 循环,只会得到 n 个字符,第一个示例最后的 | 就没了。 数字行从左往右依次拼接时,当前长度就是下一个空格的格号,所以“至少一个空格”就是 m > 当前长度,要补 m - 当前长度 个空格。 如果把跳过的数字的最后一格当作“前一个数字”,第二个示例里的 2、4、6 也会丢。 放得下的判断是 <=,写成 < 会让 n = 9, k = 9 的 9 消失。 位数可以把数字转成字符串再量长度:Python len(str(m)),JS·TS String(m).length,Java Integer.toString(m).length(),C# m.ToString().Length,C++ std::to_string(m).size(),Craykon ("" + m).长度。 C 可以用 sprintf 返回的写入字符数。 拼接字符串的方式也不同。 Java·C# 在循环里 += 每次都会复制出新字符串,所以用 StringBuilder(C# 用 Append(' ', 个数) 一次补上空格)。 Python·JS·TS·C++ std::string·Craykon 用 += 就够了,C 填进字符数组后在末尾放 '\0'。 C++ 的 size() 是无符号数,和 m 比较前先转成 int 更安全。
Pythonmain.py · 19 行
n, k = map(int, input().split())# 눈금 줄: 칸 0 ~ n, 모두 n + 1글자marks = "".join("|" if c % k == 0 else "." for c in range(n + 1))# 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다labels = ""count = 0for m in range(0, n + 1, k): t = str(m) fits = m + len(t) - 1 <= n # 마지막 칸이 n을 넘지 않는다 gap = labels == "" or m > len(labels) # 앞 숫자와 빈칸이 하나 이상 있다 if fits and gap: labels += " " * (m - len(labels)) + t count += 1print(marks)print(labels)print(count)
JavaScriptmain.js · 19 行
const [n, k] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 눈금 줄: 칸 0 ~ n, 모두 n + 1글자let marks = "";for (let c = 0; c <= n; c++) marks += c % k === 0 ? "|" : ".";// 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다let labels = "";let count = 0;for (let m = 0; m <= n; m += k) { const t = String(m); const fits = m + t.length - 1 <= n; // 마지막 칸이 n을 넘지 않는다 const gap = labels === "" || m > labels.length; // 앞 숫자와 빈칸이 하나 이상 있다 if (fits && gap) { labels += " ".repeat(m - labels.length) + t; count++; }}console.log([marks, labels, count].join("\n"));
TypeScriptmain.ts · 20 行
import { readFileSync } from "node:fs";const [n, k]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 눈금 줄: 칸 0 ~ n, 모두 n + 1글자let marks = "";for (let c = 0; c <= n; c++) marks += c % k === 0 ? "|" : ".";// 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다let labels = "";let count = 0;for (let m = 0; m <= n; m += k) { const t: string = String(m); const fits: boolean = m + t.length - 1 <= n; // 마지막 칸이 n을 넘지 않는다 const gap: boolean = labels === "" || m > labels.length; // 앞 숫자와 빈칸이 하나 이상 있다 if (fits && gap) { labels += " ".repeat(m - labels.length) + t; count++; }}console.log([marks, labels, String(count)].join("\n"));
JavaMain.java · 28 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), k = sc.nextInt(); // 눈금 줄: 칸 0 ~ n, 모두 n + 1글자 StringBuilder marks = new StringBuilder(); for (int c = 0; c <= n; c++) marks.append(c % k == 0 ? '|' : '.'); // 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다 StringBuilder labels = new StringBuilder(); int count = 0; for (int m = 0; m <= n; m += k) { String t = Integer.toString(m); boolean fits = m + t.length() - 1 <= n; // 마지막 칸이 n을 넘지 않는다 boolean gap = labels.length() == 0 || m > labels.length(); // 앞 숫자와 빈칸이 하나 이상 if (fits && gap) { labels.append(" ".repeat(m - labels.length())).append(t); count++; } } System.out.println(marks); System.out.println(labels); System.out.println(count); }}
C#Main.cs · 33 行
using System;using System.Text;class Program{ static void Main() { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(p[0]), k = int.Parse(p[1]); // 눈금 줄: 칸 0 ~ n, 모두 n + 1글자 var marks = new StringBuilder(); for (int c = 0; c <= n; c++) marks.Append(c % k == 0 ? '|' : '.'); // 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다 var labels = new StringBuilder(); int count = 0; for (int m = 0; m <= n; m += k) { string t = m.ToString(); bool fits = m + t.Length - 1 <= n; // 마지막 칸이 n을 넘지 않는다 bool gap = labels.Length == 0 || m > labels.Length; // 앞 숫자와 빈칸이 하나 이상 if (fits && gap) { labels.Append(' ', m - labels.Length).Append(t); count++; } } Console.WriteLine(marks); Console.WriteLine(labels); Console.WriteLine(count); }}
C++main.cpp · 26 行
#include <iostream>#include <string>int main() { int n, k; std::cin >> n >> k; // 눈금 줄: 칸 0 ~ n, 모두 n + 1글자 std::string marks; for (int c = 0; c <= n; c++) marks += c % k == 0 ? '|' : '.'; // 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다 std::string labels; int count = 0; for (int m = 0; m <= n; m += k) { std::string t = std::to_string(m); int len = static_cast<int>(labels.size()); // size()는 부호 없는 수라 int로 바꿔 비교한다 bool fits = m + static_cast<int>(t.size()) - 1 <= n; // 마지막 칸이 n을 넘지 않는다 bool gap = len == 0 || m > len; // 앞 숫자와 빈칸이 하나 이상 있다 if (fits && gap) { labels += std::string(m - len, ' ') + t; count++; } } std::cout << marks << '\n' << labels << '\n' << count << '\n';}
Cmain.c · 33 行
#include <stdio.h>#include <string.h>#define MAXN 5000int main(void) { int n, k; scanf("%d %d", &n, &k); /* 눈금 줄: 칸 0 ~ n, 모두 n + 1글자 */ static char marks[MAXN + 2]; for (int c = 0; c <= n; c++) marks[c] = c % k == 0 ? '|' : '.'; marks[n + 1] = '\0'; /* 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다 */ static char labels[MAXN + 2]; int len = 0, count = 0; char t[8]; for (int m = 0; m <= n; m += k) { int w = sprintf(t, "%d", m); /* sprintf는 쓴 글자 수를 돌려준다 */ int fits = m + w - 1 <= n; /* 마지막 칸이 n을 넘지 않는다 */ int gap = len == 0 || m > len; /* 앞 숫자와 빈칸이 하나 이상 있다 */ if (fits && gap) { while (len < m) labels[len++] = ' '; memcpy(labels + len, t, w); len += w; count++; } } labels[len] = '\0'; printf("%s\n%s\n%d\n", marks, labels, count); return 0;}
Craykonmain.cray · 35 行
v = 控制台.读数字();n = v[0];k = v[1];// 눈금 줄: 칸 0 ~ n, 모두 n + 1글자눈금 = "";循环 (c = 0; c <= n; c += 1){ 如果 (c % k == 0) { 눈금 += "|"; } 否则 { 눈금 += "."; }}// 숫자 줄: 0, k, 2k, ... 를 차례로 보며 쓸 수 있는 것만 뒤에 붙인다숫자줄 = "";개수 = 0;循环 (m = 0; m <= n; m += k){ t = "" + m; 맞음 = m + t.长度 - 1 <= n; // 마지막 칸이 n을 넘지 않는다 띄움 = 숫자줄 == "" || m > 숫자줄.长度; // 앞 숫자와 빈칸이 하나 이상 있다 如果 (맞음 && 띄움) { 숫자줄 += " ".重复(m - 숫자줄.长度) + t; 개수 += 1; }}控制台.输出(눈금);控制台.输出(숫자줄);控制台.输出(개수);