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);