{ }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()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

「値がない」は数の 0 とは別のものです。
ない割引価格を入れる方法:Python None、JS null、TS number | null、Java Integer(int には null を入れられません)、C# int?、C++17 std::optional<int>、Craykon なし。
C の int には「なし」がないので、bool has_sale のような真偽値を別に持ちます。
「なければ別の値」を一度に書く方法も違います:JS・TS・C# sale ?? full、C++ sale.value_or(full)。
Python・Java・C・Craykon には ?? がないので、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);