項目ごとの値を、文字で描いた横棒グラフの報告として出力する。 一行目に項目の数 n と棒のいちばん長い長さ W が空白一つで区切って与えられる。 続く n 行に項目の名前と値 v が空白一つで区切って与えられる。 すべての値のうち最大の値を M とする。 項目の棒の長さは v × W ÷ M の小数点以下を切り捨てた整数である。 M が 0 なら、すべての棒の長さは 0 である。 項目ごとに入力の順に一行を出力する。 一行は、名前、名前をいちばん長い名前の長さに合わせる空白、" |"、棒の印、空白一つ、値 v をこの順につなげたものである。 棒の印は # を棒の長さだけ書いたものである。 ただし v が 0 より大きいのに棒の長さが 0 なら、棒の印として . を一つ書く。
入力
1 ≤ n ≤ 500、1 ≤ W ≤ 100、0 ≤ v ≤ 10^9(整数)。 名前は長さ 1 ~ 20 で、英字、数字、_ だけを使う
棒の長さは掛けてから割ります。 v / M * W のように整数の割り算を先にすると、最大の値以外はほとんど 0 になります。 ところが掛けると v * W は 10 億 × 100 = 1000 億まで行き、int(約 21 億)を超えます。 C・C++ は long long、Java・C# は long で掛けます。 Python の整数には限りがなく、JS・TS・Craykon の数は 2^53 まで整数が正確なので Math.floor(v * W / M)、Craykon 数学.切り下げ(v * w / 最大) で動きます。 M が 0 なら 0 で割ることになるので先に確かめます(二つ目の例)。 同じ文字の繰り返しは Python "#" * k、JS・TS・Java "#".repeat(k)、C# new string('#', k)、C++ std::string(k, '#')、Craykon "#".繰り返し(k) です。 C は putchar を k 回呼びます。 名前をそろえるのは長さを測ることとセットです。 名前の長さは Python len(s)、JS・TS s.length、Java s.length()、C# s.Length、C strlen(s)、C++ s.size()、Craykon s.長さ で、足りない空白は(いちばん長い長さ − 名前の長さ)個です。 C の printf("%-*s", width, s) は幅を引数で受け取って左寄せしてくれます。 四捨五入すると最初の例の banana が 7.5 → 8 になるので、必ず切り捨てます。 v が 0 より大きいのに棒が 0 のとき . を忘れるのもよくある間違いです。
Pythonmain.py · 16 行
import sysdata = sys.stdin.read().split()n, w = int(data[0]), int(data[1])names = data[2::2][:n]values = [int(x) for x in data[3::2][:n]]width = max(len(s) for s in names) # 가장 긴 이름에 맞춘다top = max(values)for name, v in zip(names, values): bar = v * w // top if top > 0 else 0 # 곱한 뒤에 나눈다(먼저 나누면 0이 된다) if v > 0 and bar == 0: mark = "." else: mark = "#" * bar print(name + " " * (width - len(name)) + " |" + mark + " " + str(v))
JavaScriptmain.js · 20 行
const data = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);const n = Number(data[0]);const w = Number(data[1]);const names = [];const values = [];for (let i = 0; i < n; i++) { names.push(data[2 + 2 * i]); values.push(Number(data[3 + 2 * i]));}const width = Math.max(...names.map((s) => s.length)); // 가장 긴 이름에 맞춘다const top = Math.max(...values);const out = [];for (let i = 0; i < n; i++) { const v = values[i]; // 곱한 뒤에 나눈다. v * w는 1000억까지라 Number로 정확하다 const bar = top > 0 ? Math.floor((v * w) / top) : 0; const mark = v > 0 && bar === 0 ? "." : "#".repeat(bar); out.push(names[i] + " ".repeat(width - names[i].length) + " |" + mark + " " + v);}console.log(out.join("\n"));
TypeScriptmain.ts · 21 行
import { readFileSync } from "node:fs";const data: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const n: number = Number(data[0]);const w: number = Number(data[1]);const names: string[] = [];const values: number[] = [];for (let i = 0; i < n; i++) { names.push(data[2 + 2 * i]); values.push(Number(data[3 + 2 * i]));}const width: number = Math.max(...names.map((s) => s.length)); // 가장 긴 이름에 맞춘다const top: number = Math.max(...values);const out: string[] = [];for (let i = 0; i < n; i++) { const v: number = values[i]; // 곱한 뒤에 나눈다. v * w는 1000억까지라 number로 정확하다 const bar: number = top > 0 ? Math.floor((v * w) / top) : 0; const mark: string = v > 0 && bar === 0 ? "." : "#".repeat(bar); out.push(names[i] + " ".repeat(width - names[i].length) + " |" + mark + " " + v);}console.log(out.join("\n"));
JavaMain.java · 33 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int n = Integer.parseInt(st.nextToken()), w = Integer.parseInt(st.nextToken()); String[] names = new String[n]; long[] values = new long[n]; int width = 0; long top = 0; for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine()); names[i] = st.nextToken(); values[i] = Long.parseLong(st.nextToken()); width = Math.max(width, names[i].length()); // 가장 긴 이름에 맞춘다 top = Math.max(top, values[i]); } StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { long v = values[i]; // v * w는 1000억까지 가서 int로는 넘친다. long으로 곱한 뒤에 나눈다 int bar = top > 0 ? (int) (v * w / top) : 0; String mark = v > 0 && bar == 0 ? "." : "#".repeat(bar); out.append(names[i]).append(" ".repeat(width - names[i].length())) .append(" |").append(mark).append(' ').append(v).append('\n'); } System.out.print(out); }}
C#Main.cs · 34 行
using System;using System.Text;class Program{ static void Main() { string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(first[0]), w = int.Parse(first[1]); var names = new string[n]; var values = new long[n]; int width = 0; long top = 0; for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); names[i] = p[0]; values[i] = long.Parse(p[1]); width = Math.Max(width, names[i].Length); // 가장 긴 이름에 맞춘다 top = Math.Max(top, values[i]); } var sb = new StringBuilder(); for (int i = 0; i < n; i++) { long v = values[i]; // v * w는 1000억까지 가서 int로는 넘친다. long으로 곱한 뒤에 나눈다 int bar = top > 0 ? (int)(v * w / top) : 0; string mark = v > 0 && bar == 0 ? "." : new string('#', bar); sb.Append(names[i]).Append(' ', width - names[i].Length) .Append(" |").Append(mark).Append(' ').Append(v).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 25 行
#include <algorithm>#include <iostream>#include <string>#include <vector>int main() { int n, w; std::cin >> n >> w; std::vector<std::string> names(n); std::vector<long long> values(n); std::size_t width = 0; long long top = 0; for (int i = 0; i < n; i++) { std::cin >> names[i] >> values[i]; width = std::max(width, names[i].size()); // 가장 긴 이름에 맞춘다 top = std::max(top, values[i]); } for (int i = 0; i < n; i++) { long long v = values[i]; // v * w는 1000억까지 가서 int로는 넘친다. long long으로 곱한 뒤에 나눈다 int bar = top > 0 ? static_cast<int>(v * w / top) : 0; std::string mark = v > 0 && bar == 0 ? "." : std::string(bar, '#'); std::cout << names[i] << std::string(width - names[i].size(), ' ') << " |" << mark << ' ' << v << '\n'; }}
Cmain.c · 27 行
#include <stdio.h>#include <string.h>int main(void) { int n, w; static char names[500][24]; static long long values[500]; scanf("%d %d", &n, &w); int width = 0; long long top = 0; for (int i = 0; i < n; i++) { scanf("%23s %lld", names[i], &values[i]); int len = (int)strlen(names[i]); if (len > width) width = len; /* 가장 긴 이름에 맞춘다 */ if (values[i] > top) top = values[i]; } for (int i = 0; i < n; i++) { long long v = values[i]; /* v * w는 1000억까지 가서 int로는 넘친다. long long으로 곱한 뒤에 나눈다 */ int bar = top > 0 ? (int)(v * w / top) : 0; printf("%-*s |", width, names[i]); /* %-*s: 너비를 인자로 받아 왼쪽 맞춤 */ if (v > 0 && bar == 0) putchar('.'); for (int k = 0; k < bar; k++) putchar('#'); printf(" %lld\n", v); } return 0;}
Craykonmain.cray · 30 行
첫줄 = コンソール.数読み();n = 첫줄[0];w = 첫줄[1];이름들 = [];값들 = [];너비 = 0;최대 = 0;繰り返す (i = 0; i < n; i += 1){ p = コンソール.行読み().空白除去().分ける(); 이름들.追加(p[0]); 값들.追加(p[1].数に()); 너비 = 数学.大きい方(너비, p[0].長さ); // 가장 긴 이름에 맞춘다 최대 = 数学.大きい方(최대, p[1].数に());}繰り返す (i = 0; i < n; i += 1){ v = 값들[i]; 막대 = 0; もし (최대 > 0) { 막대 = 数学.切り下げ(v * w / 최대); // 곱한 뒤에 나눈다 } 표시 = "#".繰り返し(막대); もし (v > 0 && 막대 == 0) { 표시 = "."; } コンソール.書く(이름들[i] + " ".繰り返し(너비 - 이름들[i].長さ) + " |" + 표시 + " " + v);}