卸売市場のレシートには、買った品物の行の合間に小計の行と合計の行が書かれている。 ところが書かれた小計や合計に間違いがあるので、検算したい。 一行目にレシートの行数 n が与えられ、続く n 行にレシートが上から一行ずつ与えられる。 行は次の三つのどれかで、単語と数は空白一つで区切られている。 "ITEM p q" は一個 p ウォンの品物を q 個買った行で、この行の代金は p × q ウォンである。 "SUB s" は小計の行である。 すぐ前の SUB 行の次から(前に SUB 行がなければレシートの最初から)この行までに出た ITEM 行の代金をすべて足すと s ウォンだと書いたものである。 "TOTAL s" は合計の行である。 レシートの最初からこの行までに出た ITEM 行の代金をすべて足すと s ウォンだと書いたものである。 TOTAL 行は小計を数える区切りを切らない。 SUB 行と TOTAL 行に書かれた数は代金ではないので、どの合計にも足さない。 レシートの最後の行はいつも TOTAL 行である。 SUB 行と TOTAL 行ごとに、上から一行ずつ出力せよ。 書かれた値が実際の合計と同じなら "OK" を、違えば "FIX" と実際の合計を空白一つで区切って出力する。 実際の合計はカンマなしで数字だけを書く。
入力
1 ≤ n ≤ 10,000、1 ≤ p ≤ 10,000,000、1 ≤ q ≤ 1,000、0 ≤ s ≤ 10^15(すべて整数、先頭に 0 を付けない)
出力
SUB・TOTAL 行ごとに一行:OK または FIX と実際の合計
例 1 · stdin
6
ITEM 1200 3
ITEM 500 2
SUB 4600
ITEM 9900 1
SUB 9000
TOTAL 14500
stdout
OK
FIX 9900
OK
例 2 · stdin
4
SUB 0
ITEM 10000000 1000
SUB 10000000000
TOTAL 1410065408
n = int(input())sub = 0 # 지난 SUB 뒤로 산 물건값의 합total = 0 # 처음부터 산 물건값의 합for _ in range(n): kind, *nums = input().split() if kind == "ITEM": amount = int(nums[0]) * int(nums[1]) sub += amount total += amount else: actual = sub if kind == "SUB" else total print("OK" if int(nums[0]) == actual else f"FIX {actual}") if kind == "SUB": sub = 0 # 소계는 구역마다 다시 센다. TOTAL은 구역을 끊지 않는다
JavaScriptmain.js · 18 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);// 합계는 10^14까지: 2^53(약 9×10^15) 안이라 Number로 정확하다let sub = 0, total = 0;const out = [];for (let i = 1; i <= n; i++) { const [kind, a, b] = lines[i].trim().split(/\s+/); if (kind === "ITEM") { const amount = Number(a) * Number(b); sub += amount; total += amount; } else { const actual = kind === "SUB" ? sub : total; out.push(Number(a) === actual ? "OK" : `FIX ${actual}`); // 문자열 a와 수를 ===로 견주면 늘 false if (kind === "SUB") sub = 0; }}console.log(out.join("\n"));
TypeScriptmain.ts · 19 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);// 합계는 10^14까지: 2^53(약 9×10^15) 안이라 number로 정확하다let sub = 0, total = 0;const out: string[] = [];for (let i = 1; i <= n; i++) { const [kind, a, b] = lines[i].trim().split(/\s+/); if (kind === "ITEM") { const amount: number = Number(a) * Number(b); sub += amount; total += amount; } else { const actual: number = kind === "SUB" ? sub : total; out.push(Number(a) === actual ? "OK" : `FIX ${actual}`); if (kind === "SUB") sub = 0; }}console.log(out.join("\n"));
JavaMain.java · 29 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer;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()); long sub = 0, total = 0; // 합계는 10^14까지: int로는 넘친다 StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { StringTokenizer st = new StringTokenizer(in.readLine()); String kind = st.nextToken(); if (kind.equals("ITEM")) { // 문자열은 ==가 아니라 equals로 견준다 // 값 × 개수도 10^10까지: 곱하기 전에 long으로 long amount = Long.parseLong(st.nextToken()) * Long.parseLong(st.nextToken()); sub += amount; total += amount; } else { long actual = kind.equals("SUB") ? sub : total; long claim = Long.parseLong(st.nextToken()); out.append(claim == actual ? "OK" : "FIX " + actual).append('\n'); if (kind.equals("SUB")) sub = 0; } } System.out.print(out); }}
C#Main.cs · 30 行
using System;using System.Text;class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); long sub = 0, total = 0; // 합계는 10^14까지: int로는 넘친다 var out_ = new StringBuilder(); for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); if (p[0] == "ITEM") { // 값 × 개수도 10^10까지: 곱하기 전에 long으로 long amount = long.Parse(p[1]) * long.Parse(p[2]); sub += amount; total += amount; } else { long actual = p[0] == "SUB" ? sub : total; out_.Append(long.Parse(p[1]) == actual ? "OK" : "FIX " + actual).Append('\n'); if (p[0] == "SUB") sub = 0; } } Console.Write(out_); }}
C++main.cpp · 26 行
#include <iostream>#include <string>int main() { std::ios::sync_with_stdio(false); int n; std::cin >> n; long long sub = 0, total = 0; // 합계는 10^14까지: int로는 넘친다 for (int i = 0; i < n; i++) { std::string kind; std::cin >> kind; if (kind == "ITEM") { long long p, q; // 값 × 개수도 10^10까지 std::cin >> p >> q; sub += p * q; total += p * q; } else { long long claim; std::cin >> claim; long long actual = kind == "SUB" ? sub : total; if (claim == actual) std::cout << "OK\n"; else std::cout << "FIX " << actual << '\n'; if (kind == "SUB") sub = 0; } }}
Cmain.c · 27 行
#include <stdio.h>#include <string.h>int main(void) { int n; scanf("%d", &n); long long sub = 0, total = 0; /* 합계는 10^14까지: int로는 넘친다 */ for (int i = 0; i < n; i++) { char kind[8]; scanf("%7s", kind); if (strcmp(kind, "ITEM") == 0) { /* 문자열은 ==가 아니라 strcmp로 견준다 */ long long p, q; /* 값 × 개수도 10^10까지 */ scanf("%lld %lld", &p, &q); sub += p * q; total += p * q; } else { long long claim; scanf("%lld", &claim); int is_sub = strcmp(kind, "SUB") == 0; long long actual = is_sub ? sub : total; if (claim == actual) puts("OK"); else printf("FIX %lld\n", actual); if (is_sub) sub = 0; } } return 0;}
Craykonmain.cray · 34 行
n = コンソール.行読み().数に();sub = 0; // 지난 SUB 뒤로 산 물건값의 합total = 0; // 처음부터 산 물건값의 합(10^14까지: 2^53 안이라 정확하다)繰り返す (i = 0; i < n; i++){ p = コンソール.行読み().分ける(); もし (p[0] == "ITEM") { // 나눈 조각은 문자열이다: 수로 바꾼 다음 곱한다 amount = p[1].数に() * p[2].数に(); sub += amount; total += amount; } でなければ { actual = total; もし (p[0] == "SUB") { actual = sub; } もし (p[1].数に() == actual) { コンソール.書く("OK"); } でなければ { コンソール.書く("FIX " + actual); } もし (p[0] == "SUB") { sub = 0; } }}