공장 창고에 부품이 들어올 때마다 "부품코드 수량"이 한 줄씩 적힌다.
첫 줄에 기록 수 n이, 다음 n줄에 기록이 주어지고, 마지막 줄에 범위의 시작 lo와 끝 hi가 빈칸 하나로 띄워 주어진다.
같은 부품코드의 수량은 모두 더한다.
부품코드는 문자열 그대로 비교한다. 그래서 "a7"과 "A7"은 다른 코드다.
코드의 차례는 글자 코드(ASCII) 순이다. 앞 글자부터 하나씩 비교해 처음 다른 글자의 코드가 작은 쪽이 앞이고, 한쪽이 다른 쪽의 앞부분이면 짧은 쪽이 앞이다.
글자 코드는 숫자 0~9가 48~57, 대문자 A~Z가 65~90, 소문자 a~z가 97~122라서, "B10"은 "B9"보다 앞이고 "Z"는 "a"보다 앞이다.
이 차례로 lo 이상 hi 이하인 부품코드를 차례대로 한 줄에 하나씩 "부품코드 수량합"으로 출력하라.
lo와 hi는 기록에 없는 코드일 수도 있다.
그런 코드가 하나도 없으면 "없음"을 출력하라.
입력
1 ≤ n ≤ 5,000, 1 ≤ 수량 ≤ 1,000(정수). 부품코드와 lo, hi는 영어 대문자·소문자·숫자로 된 1~6글자이고, 위의 차례로 lo는 hi보다 뒤가 아니다
출력
범위 안의 코드마다 한 줄(코드, 수량합), 코드의 차례대로. 없으면 none 한 줄
예시 1 · stdin
6
B9 4
a7 2
B10 5
A3 1
B9 6
b1 3
B b
stdout
B10 5
B9 10
a7 2
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
열쇠를 정렬된 채로 두는 사전이 있는 언어와 없는 언어로 나뉘어요. Java TreeMap은 subMap(lo, true, hi, true)로 양 끝을 포함한 범위를 바로 잘라 주고, C++ std::map은 lower_bound(lo)부터 upper_bound(hi) 앞까지 돌면 돼요. C# SortedDictionary도 정렬해 두지만 범위 함수가 없어서 돌면서 걸러요. Python dict, JS·TS Map, 크레이콘 사전은 넣은 차례라서 열쇠를 꺼내 정렬해야 해요: Python sorted(d), JS·TS [...m.keys()].sort(), 크레이콘 열쇠목록을 정렬(). 이 문제의 함정은 '사전 순'이 언어마다 같은 뜻이 아니라는 거예요. Python의 <·sorted, JS·TS의 <·sort(), Java compareTo, C++ std::string의 <, C strcmp, 크레이콘의 <·정렬()은 글자 코드 순이에요. 그런데 JS localeCompare는 사람이 읽는 순서라 "a7"이 "B10"보다 앞에 와요. C#은 string.Compare와 기준 없는 SortedDictionary·List.Sort가 기본으로 문화권 규칙을 쓰기 때문에 StringComparer.Ordinal·string.CompareOrdinal을 꼭 줘야 해요(.NET을 문화권 데이터 없이 돌리는 InvariantGlobalization 환경에서만 우연히 글자 코드 순이 돼요). 대소문자를 무시하는 정렬(key=str.lower)도 틀려요. 그리고 범위는 양 끝을 포함하고, "AB"보다 "ABC"가 뒤라는 것도 잊지 말아요.
Pythonmain.py · 13 줄
n = int(input())total = {}for _ in range(n): code, qty = input().split() total[code] = total.get(code, 0) + int(qty)lo, hi = input().split()# 문자열의 <, sorted는 글자 코드 순이다(숫자 < 대문자 < 소문자)found = [code for code in sorted(total) if lo <= code <= hi]if found: for code in found: print(code, total[code])else: print("없음")
JavaScriptmain.js · 11 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const total = new Map();for (let i = 1; i <= n; i++) { const [code, qty] = lines[i].trim().split(" "); total.set(code, (total.get(code) ?? 0) + Number(qty));}const [lo, hi] = lines[n + 1].trim().split(" ");// sort()는 기준 없이 쓰면 글자 코드 순이다. localeCompare는 사람이 읽는 순(a < B)이라 쓰지 않는다const found = [...total.keys()].filter((code) => lo <= code && code <= hi).sort();console.log(found.length ? found.map((code) => `${code} ${total.get(code)}`).join("\n") : "없음");
TypeScriptmain.ts · 12 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const total = new Map<string, number>();for (let i = 1; i <= n; i++) { const [code, qty]: string[] = lines[i].trim().split(" "); total.set(code, (total.get(code) ?? 0) + Number(qty));}const [lo, hi]: string[] = lines[n + 1].trim().split(" ");// sort()는 기준 없이 쓰면 글자 코드 순이다const found: string[] = [...total.keys()].filter((code) => lo <= code && code <= hi).sort();console.log(found.length ? found.map((code) => `${code} ${total.get(code)}`).join("\n") : "없음");
JavaMain.java · 29 줄
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Map;import java.util.NavigableMap;import java.util.StringTokenizer;import java.util.TreeMap;public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine().trim()); // TreeMap은 열쇠를 compareTo 순(글자 코드 순)으로 늘 정렬해 둔다 TreeMap<String, Integer> total = new TreeMap<>(); for (int i = 0; i < n; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); total.merge(st.nextToken(), Integer.parseInt(st.nextToken()), Integer::sum); } StringTokenizer st = new StringTokenizer(br.readLine()); String lo = st.nextToken(); String hi = st.nextToken(); // 양 끝을 포함하는 범위 NavigableMap<String, Integer> range = total.subMap(lo, true, hi, true); StringBuilder out = new StringBuilder(); for (Map.Entry<String, Integer> e : range.entrySet()) { out.append(e.getKey()).append(' ').append(e.getValue()).append('\n'); } System.out.print(range.isEmpty() ? "없음\n" : out); }}
C#Main.cs · 28 줄
using System;using System.Collections.Generic;using System.Text;class Program{ static void Main() { int n = int.Parse(Console.ReadLine().Trim()); // 문자열 비교는 문화권 규칙(a < B)이 기본이라, 글자 코드 순인 Ordinal을 꼭 준다 var total = new SortedDictionary<string, int>(StringComparer.Ordinal); for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); total.TryGetValue(p[0], out int t); total[p[0]] = t + int.Parse(p[1]); } string[] r = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); string lo = r[0], hi = r[1]; var sb = new StringBuilder(); foreach (var e in total) { if (string.CompareOrdinal(e.Key, lo) >= 0 && string.CompareOrdinal(e.Key, hi) <= 0) sb.Append(e.Key).Append(' ').Append(e.Value).Append('\n'); } Console.Write(sb.Length > 0 ? sb.ToString() : "없음\n"); }}
C++main.cpp · 24 줄
#include <iostream>#include <map>#include <string>int main() { std::ios::sync_with_stdio(false); int n; std::cin >> n; // std::map은 열쇠를 글자 코드 순으로 정렬해 둔다 std::map<std::string, int> total; for (int i = 0; i < n; i++) { std::string code; int qty; std::cin >> code >> qty; total[code] += qty; } std::string lo, hi; std::cin >> lo >> hi; // lower_bound(lo): lo 이상인 첫 열쇠, upper_bound(hi): hi보다 큰 첫 열쇠 auto first = total.lower_bound(lo); auto last = total.upper_bound(hi); if (first == last) std::cout << "없음\n"; for (auto it = first; it != last; ++it) std::cout << it->first << ' ' << it->second << '\n';}
Cmain.c · 45 줄
#include <stdio.h>#include <stdlib.h>#include <string.h>/* C에는 사전이 없다. 코드와 합계를 배열에 모으고, strcmp(글자 코드 순)로 정렬한다 */typedef struct { char code[8]; int total;} Item;static Item items[5000];static int by_code(const void *a, const void *b) { return strcmp(((const Item *)a)->code, ((const Item *)b)->code);}int main(void) { int n, m = 0; scanf("%d", &n); for (int i = 0; i < n; i++) { char code[16]; int qty; scanf("%15s %d", code, &qty); int j = 0; while (j < m && strcmp(items[j].code, code) != 0) j++; if (j == m) { strcpy(items[m].code, code); items[m].total = 0; m++; } items[j].total += qty; } char lo[16], hi[16]; scanf("%15s %15s", lo, hi); qsort(items, m, sizeof(Item), by_code); int shown = 0; for (int j = 0; j < m; j++) { if (strcmp(items[j].code, lo) >= 0 && strcmp(items[j].code, hi) <= 0) { printf("%s %d\n", items[j].code, items[j].total); shown++; } } if (shown == 0) puts("없음"); return 0;}
Craykonmain.cray · 30 줄
n = 콘솔.줄읽기().수로변환();total = 사전();반복 (i = 0; i < n; i++){ p = 콘솔.줄읽기().공백제거().나누기(" "); 만약 (!total.있나(p[0])) { total[p[0]] = 0; } total[p[0]] = total[p[0]] + p[1].수로변환();}r = 콘솔.줄읽기().공백제거().나누기(" ");lo = r[0];hi = r[1];// 열쇠목록은 넣은 차례다. 정렬()은 문자열을 글자 코드 순으로 늘어놓는다codes = total.열쇠목록;codes.정렬();shown = 0;각각 (code 에서 codes){ 만약 (lo <= code && code <= hi) { 콘솔.쓰기(code + " " + total[code]); shown++; }}만약 (shown == 0){ 콘솔.쓰기("없음");}