宅配会社が、箱の重さと届け先の地域で料金を決める。 一行目に、島や山間部のような遠い地域の数 k が、二行目に遠い地域の番号 k 個が空白で区切って与えられる。 三行目に箱の数 n が与えられ、続く n 行に箱ごとの届け先の地域番号、重さ(グラム)、配送の種類が空白で区切って与えられる。 配送の種類は通常配送 "N" か速達 "X" である。 基本料金は重さで決める。 1,000g 以下なら 3,500 ウォン、1,000g を超え 3,000g 以下なら 4,000 ウォン、3,000g を超え 7,000g 以下なら 5,000 ウォンである。 7,000g を超え 15,000g 以下なら 6,500 ウォン、15,000g を超え 25,000g 以下なら 8,500 ウォンである。 25,000g を超える箱は受け付けない。 届け先の地域番号が遠い地域の番号のどれかと同じなら 3,000 ウォンを足す。 速達は、届け先が遠い地域でなく、重さが 15,000g 以下のときだけでき、そのとき 2,000 ウォンを足す。 速達ができない箱も受け付けない。 箱ごとの料金を一行に一つずつ入力の順に出力し、受け付けない箱は "受付不可" を出力せよ。 最後の行に、受け付けた箱の数と、受け付けた箱の料金の合計を空白一つで区切って出力せよ。
入力
1 ≤ k ≤ 100、1 ≤ n ≤ 1,000、地域番号は 1 以上 999 以下の整数(先頭に 0 を付けない)で、遠い地域の番号どうしは異なる、1 ≤ 重さ ≤ 40,000
出力
箱ごとに料金または "受付不可"、最後の行に受け付けた箱の数と料金の合計
例 1 · stdin
3
12 305 7
7
12 1000 N
112 1001 N
305 3000 X
7 25000 N
50 15000 X
50 15001 X
9 25001 N
stdout
6500
4000
受付不可
11500
8500
受付不可
受付不可
4 30500
main.py
エラー一覧00F8 ↓ · ⇧F8 ↑
入力(stdin)
実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。
$ 準備完了
コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。
ほかの言語では?言語別の解答を見る · 8 言語の解答
一つ目の落とし穴は、遠い地域かどうかを聞く「含まれるか」の判定です。 二行目を文字列のまま置いて Python "12" in line、JS・TS line.includes("12")、Java line.contains("12")、C# line.Contains("12")、C strstr のように探すと、部分文字列を探すので "112" の中の "12" も見つかります。 番号を数に変えて集めておき、Python の set の in、JS・TS Set.has、Java HashSet.contains、C# HashSet<int>.Contains、C++ unordered_set::count(C++20 は contains)で聞きます。 C には集合がありませんが、番号が 1〜999 なので is_remote[番号] という表一つが集合になります。 Craykon は コンソール.数読み() で読んだ数のリストに リスト.含む(r) を使います。 リストの数と行から切り出した文字列("12")を比べても等しくならないので、数に() でそろえます。 二つ目の落とし穴は重さの区分です。 多分岐は上から最初に真になった枝一つだけを実行するので、小さい区分から <= で聞いて else if(Python elif、Craykon でなければ もし)でつなげば、下の端は聞かなくて済みます。 else なしで if だけを並べると、500g の箱でも後の if が全部真なので、料金が 8,500 ウォンで上書きされます。 < で聞くと、ちょうど 1,000g の箱が一つ上の区分になります。 三つ目に、速達の条件は二つとも真でなければならないので、Python は not far and w <= 15000、ほかの七つの言語は !far && w <= 15000 です。 || と書くと、遠い地域の軽い箱にも速達ができてしまいます。 Java で "X" を == で比べると、内容ではなく同じオブジェクトかを聞くことになるので equals を使います(C#・Python・JS・Craykon の == は内容を比べます)。
Pythonmain.py · 40 行
def base_fee(w): # 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다 if w <= 1000: return 3500 elif w <= 3000: return 4000 elif w <= 7000: return 5000 elif w <= 15000: return 6500 elif w <= 25000: return 8500 else: return None # 25,000g을 넘으면 받지 않는다input() # kremote = set(map(int, input().split())) # 수로 바꾼 집합: "12"가 "112" 안에 있다고 착각하지 않는다n = int(input())accepted = 0total = 0for _ in range(n): r, w, s = input().split() r, w = int(r), int(w) fee = base_fee(w) far = r in remote if fee is not None and far: fee += 3000 if fee is not None and s == "X": if not far and w <= 15000: # 빠른 배송은 두 조건을 모두 지켜야 한다 fee += 2000 else: fee = None if fee is None: print("受付不可") else: print(fee) accepted += 1 total += feeprint(accepted, total)
JavaScriptmain.js · 36 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");// 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다const baseFee = (w) => { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return null; // 25,000g을 넘으면 받지 않는다};// 수로 바꾼 Set: 줄 문자열에 includes를 쓰면 "12"가 "112" 안에서 찾아진다const remote = new Set(lines[1].trim().split(/\s+/).filter((x) => x !== "").map(Number));const n = Number(lines[2]);const out = [];let accepted = 0;let total = 0;for (let i = 0; i < n; i++) { const [rText, wText, s] = lines[3 + i].trim().split(/\s+/); const r = Number(rText); const w = Number(wText); let fee = baseFee(w); const far = remote.has(r); if (fee !== null && far) fee += 3000; if (fee !== null && s === "X") { if (!far && w <= 15000) fee += 2000; // 빠른 배송은 두 조건을 모두 지켜야 한다 else fee = null; } if (fee === null) out.push("受付不可"); else { out.push(String(fee)); accepted++; total += fee; }}out.push(`${accepted} ${total}`);console.log(out.join("\n"));
TypeScriptmain.ts · 37 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");// 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다const baseFee = (w: number): number | null => { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return null; // 25,000g을 넘으면 받지 않는다};// 수로 바꾼 Set: 줄 문자열에 includes를 쓰면 "12"가 "112" 안에서 찾아진다const remote = new Set(lines[1].trim().split(/\s+/).filter((x) => x !== "").map(Number));const n = Number(lines[2]);const out: string[] = [];let accepted = 0;let total = 0;for (let i = 0; i < n; i++) { const [rText, wText, s] = lines[3 + i].trim().split(/\s+/); const r = Number(rText); const w = Number(wText); let fee: number | null = baseFee(w); const far = remote.has(r); if (fee !== null && far) fee += 3000; if (fee !== null && s === "X") { if (!far && w <= 15000) fee += 2000; // 빠른 배송은 두 조건을 모두 지켜야 한다 else fee = null; } if (fee === null) out.push("受付不可"); else { out.push(String(fee)); accepted++; total += fee; }}out.push(`${accepted} ${total}`);console.log(out.join("\n"));
JavaMain.java · 51 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.HashSet;import java.util.Set;public class Main { static final int REJECT = -1; // 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다 static int baseFee(int w) { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return REJECT; // 25,000g을 넘으면 받지 않는다 } public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); // k Set<Integer> remote = new HashSet<>(); for (String c : in.readLine().trim().split("\\s+")) { if (!c.isEmpty()) remote.add(Integer.parseInt(c)); } int n = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); int accepted = 0; long total = 0; for (int i = 0; i < n; i++) { String[] p = in.readLine().trim().split("\\s+"); int r = Integer.parseInt(p[0]), w = Integer.parseInt(p[1]); int fee = baseFee(w); boolean far = remote.contains(r); if (fee != REJECT && far) fee += 3000; if (fee != REJECT && p[2].equals("X")) { // 문자열은 ==가 아니라 equals로 비교한다 if (!far && w <= 15000) fee += 2000; // 빠른 배송은 두 조건을 모두 지켜야 한다 else fee = REJECT; } if (fee == REJECT) { out.append("受付不可\n"); } else { out.append(fee).append('\n'); accepted++; total += fee; } } out.append(accepted).append(' ').append(total).append('\n'); System.out.print(out); }}
C#Main.cs · 53 行
using System;using System.Collections.Generic;using System.Linq;using System.Text;class Program{ // 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다 static int? BaseFee(int w) { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return null; // 25,000g을 넘으면 받지 않는다 } static void Main() { Console.ReadLine(); // k var remote = new HashSet<int>(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse)); int n = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); int accepted = 0; long total = 0; for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int r = int.Parse(p[0]), w = int.Parse(p[1]); int? fee = BaseFee(w); bool far = remote.Contains(r); if (fee != null && far) fee += 3000; if (fee != null && p[2] == "X") { if (!far && w <= 15000) fee += 2000; // 빠른 배송은 두 조건을 모두 지켜야 한다 else fee = null; } if (fee == null) { sb.Append("受付不可\n"); } else { sb.Append(fee.Value).Append('\n'); accepted++; total += fee.Value; } } sb.Append(accepted).Append(' ').Append(total).Append('\n'); Console.Write(sb); }}
C++main.cpp · 48 行
#include <iostream>#include <optional>#include <string>#include <unordered_set>// 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다std::optional<int> baseFee(int w) { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return std::nullopt; // 25,000g을 넘으면 받지 않는다}int main() { int k, n; std::cin >> k; std::unordered_set<int> remote; for (int i = 0; i < k; i++) { int code; std::cin >> code; remote.insert(code); } std::cin >> n; int accepted = 0; long long total = 0; for (int i = 0; i < n; i++) { int r, w; std::string s; std::cin >> r >> w >> s; std::optional<int> fee = baseFee(w); bool far = remote.count(r) > 0; // C++20부터는 remote.contains(r) if (fee && far) *fee += 3000; if (fee && s == "X") { if (!far && w <= 15000) *fee += 2000; // 빠른 배송은 두 조건을 모두 지켜야 한다 else fee.reset(); } if (!fee) { std::cout << "受付不可\n"; } else { std::cout << *fee << '\n'; accepted++; total += *fee; } } std::cout << accepted << ' ' << total << '\n';}
Cmain.c · 50 行
#include <stdio.h>#include <string.h>#define REJECT -1/* 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다 */int base_fee(int w) { if (w <= 1000) return 3500; else if (w <= 3000) return 4000; else if (w <= 7000) return 5000; else if (w <= 15000) return 6500; else if (w <= 25000) return 8500; else return REJECT; /* 25,000g을 넘으면 받지 않는다 */}int main(void) { /* 지역 번호는 1~999라서 번호를 칸 번호로 쓰는 표가 곧 "들어 있나" 검사다 */ static int is_remote[1000]; int k, n; scanf("%d", &k); for (int i = 0; i < k; i++) { int code; scanf("%d", &code); is_remote[code] = 1; } scanf("%d", &n); int accepted = 0; long total = 0; for (int i = 0; i < n; i++) { int r, w; char s[4]; scanf("%d %d %3s", &r, &w, s); int fee = base_fee(w); int far = is_remote[r]; if (fee != REJECT && far) fee += 3000; if (fee != REJECT && strcmp(s, "X") == 0) { if (!far && w <= 15000) fee += 2000; /* 빠른 배송은 두 조건을 모두 지켜야 한다 */ else fee = REJECT; } if (fee == REJECT) { printf("受付不可\n"); } else { printf("%d\n", fee); accepted++; total += fee; } } printf("%d %ld\n", accepted, total); return 0;}
Craykonmain.cray · 65 行
// 아래 칸부터 차례로 묻는다: 앞 조건이 거짓일 때만 다음 조건을 보니 칸의 아래 끝은 따로 묻지 않는다기본요금(w){ もし (w <= 1000) { 返す 3500; } でなければ もし (w <= 3000) { 返す 4000; } でなければ もし (w <= 7000) { 返す 5000; } でなければ もし (w <= 15000) { 返す 6500; } でなければ もし (w <= 25000) { 返す 8500; } 返す -1; // 25,000g을 넘으면 받지 않는다}コンソール.行読み(); // kremote = コンソール.数読み(); // 수 목록: 문자열 "12 305"에서 찾으면 "12"가 "112" 안에서도 찾아진다n = コンソール.行読み().数に();accepted = 0;total = 0;繰り返す (i = 0; i < n; i++){ 칸 = コンソール.行読み().分ける(); r = 칸[0].数に(); w = 칸[1].数に(); fee = 기본요금(w); far = remote.含む(r); もし (fee != -1 && far) { fee += 3000; } もし (fee != -1 && 칸[2] == "X") { もし (!far && w <= 15000) { fee += 2000; } でなければ { fee = -1; } } もし (fee == -1) { コンソール.書く("受付不可"); } でなければ { コンソール.書く(fee); accepted += 1; total += fee; }}コンソール.書く(accepted + " " + total);