{ }codelper
빈 값(null)P0281

할인가가 없으면 정가로

벼룩시장에 물건 n개가 나왔다. 첫 줄에 n이 주어지고, 다음 n줄에 물건마다 정가와 할인가가 빈칸 하나로 띄워 주어진다. 할인가를 정하지 않은 물건은 할인가 자리에 수 대신 - 가 적혀 있다. 물건값은 할인가가 있으면 할인가이고, 할인가가 없으면 정가이다. 할인가 0은 거저 준다는 뜻이며, 할인가가 있는 것으로 본다. 첫 줄에 물건값 n개의 합을, 둘째 줄에 할인가가 없는 물건의 수를 출력하라.

입력
1 ≤ n ≤ 1,000, 1 ≤ 정가 ≤ 1,000,000, 할인가는 - 이거나 0 ≤ 할인가 ≤ 정가인 정수
출력
두 줄: 물건값의 합, 할인가가 없는 물건의 수.
합은 쉼표 없이 숫자만 쓴다
예시 1 · stdin
4
5000 3000
2000 -
1500 0
800 800
stdout
5800
1
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

'값이 없음'은 수 0과 다른 것이에요.
없는 할인가를 담는 방법: Python None, JS null, TS number | null, Java Integer(int에는 null을 못 담아요), C# int?, C++17 std::optional<int>, 크레이콘 빈값.
C의 int에는 '없음'이 없어서 bool has_sale 같은 참·거짓을 따로 둬요.
'없으면 다른 값'을 한 번에 쓰는 방법도 달라요: JS·TS·C# sale ?? full, C++ sale.value_or(full).
Python·Java·C·크레이콘에는 ??가 없어서 if sale is None, sale == null, sale == 빈값처럼 물어서 갈라요.
함정 셋: ① Python sale or full, JS sale || full은 null뿐 아니라 0도 거짓으로 봐서, 거저 주는 물건(할인가 0)에 정가를 받아요.
!sale·not sale로 '없음'을 세어도 0이 함께 세어져요.
② '없음'을 0으로 대신하면 진짜 할인가 0과 구별되지 않아요.
C atoi("-")는 조용히 0을 줘요.
③ -인지 확인하지 않고 수로 바꾸면 JS Number("-")는 NaN이 되어 합까지 NaN이 되고, Python int("-")는 ValueError, Java Integer.parseInt("-")는 NumberFormatException으로 멈춰요.

Pythonmain.py · 13 줄
n = int(input())total = 0missing = 0for _ in range(n):    full, word = input().split()    sale = None if word == "-" else int(word)  # 할인가가 없으면 None    if sale is None:        missing += 1        total += int(full)    else:        total += saleprint(total)print(missing)
JavaScriptmain.js · 12 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);let total = 0;let missing = 0;for (let i = 1; i <= n; i++) {  const [full, word] = lines[i].trim().split(" ");  const sale = word === "-" ? null : Number(word); // 할인가가 없으면 null  if (sale === null) missing++;  total += sale ?? Number(full); // ??는 null일 때만 오른쪽 값을 쓴다(0은 그대로 0)}console.log(total);console.log(missing);
TypeScriptmain.ts · 13 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);let total = 0;let missing = 0;for (let i = 1; i <= n; i++) {  const [full, word] = lines[i].trim().split(" ");  const sale: number | null = word === "-" ? null : Number(word); // 할인가가 없으면 null  if (sale === null) missing++;  total += sale ?? Number(full); // ??는 null일 때만 오른쪽 값을 쓴다(0은 그대로 0)}console.log(total);console.log(missing);
JavaMain.java · 26 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        int total = 0;        int missing = 0;        for (int i = 0; i < n; i++) {            String[] parts = in.readLine().trim().split(" ");            int full = Integer.parseInt(parts[0]);            // int는 null을 담을 수 없어 Integer를 쓴다            Integer sale = parts[1].equals("-") ? null : Integer.valueOf(parts[1]);            if (sale == null) {                missing++;                total += full;            } else {                total += sale;            }        }        System.out.println(total);        System.out.println(missing);    }}
C#Main.cs · 21 줄
using System; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        int total = 0;        int missing = 0;        for (int i = 0; i < n; i++)        {            string[] parts = Console.ReadLine().Trim().Split(' ');            int full = int.Parse(parts[0]);            int? sale = parts[1] == "-" ? null : int.Parse(parts[1]); // int? 는 null도 담는 int            if (sale == null) missing++;            total += sale ?? full; // ??는 null일 때만 오른쪽 값을 쓴다        }        Console.WriteLine(total);        Console.WriteLine(missing);    }}
C++main.cpp · 20 줄
#include <iostream>#include <optional>#include <string> int main() {    int n;    std::cin >> n;    int total = 0;    int missing = 0;    for (int i = 0; i < n; i++) {        int full;        std::string word;        std::cin >> full >> word;        std::optional<int> sale;  // 처음에는 값이 없음        if (word != "-") sale = std::stoi(word);        if (!sale) missing++;        total += sale.value_or(full);  // 값이 없을 때만 full을 쓴다    }    std::cout << total << '\n' << missing << '\n';}
Cmain.c · 26 줄
#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <string.h> int main(void) {    int n;    if (scanf("%d", &n) != 1) return 0;    int total = 0;    int missing = 0;    for (int i = 0; i < n; i++) {        int full;        char word[16];        if (scanf("%d %15s", &full, word) != 2) return 0;        // C의 int에는 '없음'이 없어서 참·거짓 하나를 따로 둔다        bool has_sale = strcmp(word, "-") != 0;        if (has_sale) {            total += atoi(word);        } else {            missing++;            total += full;        }    }    printf("%d\n%d\n", total, missing);    return 0;}
Craykonmain.cray · 24 줄
n = 콘솔.줄읽기().수로변환();total = 0;missing = 0;반복 (i = 0; i < n; i++){    parts = 콘솔.줄읽기().공백제거().나누기(" ");    full = parts[0].수로변환();    sale = 빈값; // 할인가가 없으면 빈값    만약 (parts[1] != "-")    {        sale = parts[1].수로변환();    }    만약 (sale == 빈값)    {        missing++;        total += full;    }    아니면    {        total += sale;    }}콘솔.쓰기(total);콘솔.쓰기(missing);