A game of darts is played for n rounds.
In one round the dart is thrown k times, and each throw scores from 0 to 10 points.
A throw that scores 0 is called a 'miss', and a round with no miss at all is called a 'clean round'.
Three values are found for each round.
The round score is the sum of the throw scores of that round. However, if the round just before it was a clean round, it is twice that sum.
The first round has no round before it, so it is not doubled.
The running total is the sum of the round scores from the first round up to that round.
The first-miss position says which throw of the round was the first to score 0 (the first throw is number 1). If the round has no miss, it is 0.
When the game is over, three more values are found.
They are the number of the round with the highest round score (the earliest one if there are several), that round's round score, and the largest number of clean rounds in a row without a break (0 if there is no clean round).
In the example, round 2 is clean, but round 1 had a miss, so its round score stays 8.
Round 3 is 12, twice 6, because round 2 was clean.
Round 4 has a miss itself, but round 3 was clean, so it is 12, twice 6.
The round score 12 appears twice, so the highest round is round 3, which came first, and the clean rounds 2 and 3 make a run of 2.
Input
The first line has n. Each of the next n lines describes one round: the number of throws k followed by the k throw scores in the order thrown, separated by single spaces. 1 ≤ n ≤ 1,000, 1 ≤ k ≤ 20, each score is an integer from 0 to 10
Output
For each round print one line with the round score, the running total and the first-miss position, in this order, separated by single spaces. On the last line print the number of the round with the highest round score, that round's round score, and the longest run of clean rounds, separated by single spaces
Example 1 · stdin
4
3 5 0 2
2 4 4
3 1 2 3
2 0 6
stdout
7 7 2
8 15 0
12 27 0
12 39 1
3 12 2
main.py
Error List00F8 ↓ · ⇧F8 ↑
Input (stdin)
When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).
$ Ready
Open this on a computer to write and run code. On mobile you can read the problem and the solutions.
In other languagesShow solutions by language · 8 languages
The values in this problem have three lifetimes: values that last the whole game (running total, best round, current run), values that start afresh every round (round score, first-miss position), and a value used once in the next round (was the previous round clean). Where a variable is declared is its lifetime. In C, C++, Java, C#, JS and TS (let) a variable declared inside the loop is created anew each round and disappears when the block ends. Trap one (shadowing): declaring the same name again inside an if quietly creates a new variable that hides the outer one in C, C++, JS and TS (let). if (prev) { int score = raw * 2; } cannot change the outer score, so round 3 of the example comes out as 6. Java refuses to compile with variable score is already defined and C# with CS0136, which prevents this mistake. JS var is scoped to the whole function, not the block, so var v = 6 inside an if changes the outer v. Python has neither block scope nor declarations, so a value assigned inside an if is simply visible outside. Trap two (the loop variable): the i of for (int i …) used after the loop is a compile error in C, C++, Java, C# and TS, and a ReferenceError with JS let. In Python i survives for i in range(k), but after a full run its value is k - 1, not k. So the C-style test 'not found if i == k' makes the first-miss position of a clean round come out as k instead of 0 (round 2 of the example gives 2). Record the position right where it is found, or use for … else. Trap three: put a per-round value outside the loop and the previous round's value stays; put a whole-game value inside the loop and it is 0 again every round. Trap four: change 'was the previous round clean' only after computing this round's score. Change it first and the round is doubled by its own result. Trap five: the current run goes back to 0 on a round with a miss, and on equal scores the earlier round wins, so compare with >, not >=. Initial values differ too. Reading a local variable in C and C++ before a value is stored is undefined behaviour, so there is no telling what value comes out, while Java (might not have been initialized) and C# (CS0165) refuse to compile. Craykon has no separate declaration: a variable comes into being where it first gets a value. A variable first made inside a block or inside for (i = 1; …) disappears when that block ends, and using it outside stops before running with a 'name not made yet' error. So make the whole-game values before the loop, as in total = 0;. Storing into a name that already exists always changes that outer variable, so the shadowing mistake cannot happen.
Pythonmain.py · 45 lines
import sysdef main(): lines = sys.stdin.read().split("\n") n = int(lines[0]) # 놀이 내내 살아 있는 값 total = 0 best_round = 0 best_score = -1 streak = 0 # 지금 이어지는 깨끗한 판 수 longest = 0 prev_clean = False # 바로 앞 판이 깨끗했는가 (다음 판에서 한 번 쓰고 바뀐다) out = [] for r in range(1, n + 1): throws = [int(v) for v in lines[r].split()][1:] # 이 판에서만 쓰는 값: 판마다 새로 시작한다 miss = 0 for i, s in enumerate(throws): if s == 0: miss = i + 1 # 반복이 끝난 뒤의 i에 기대지 않고, 찾은 그 자리에서 적는다 break score = sum(throws) if prev_clean: score *= 2 # if 안에서 바꿔도 같은 score다 (Python에는 블록 범위가 없다) total += score if score > best_score: best_score = score best_round = r clean = miss == 0 if clean: streak += 1 longest = max(longest, streak) else: streak = 0 prev_clean = clean # 이 판의 결과를 다 쓴 뒤에 넘긴다 out.append(f"{score} {total} {miss}") out.append(f"{best_round} {best_score} {longest}") print("\n".join(out))main()
JavaScriptmain.js · 46 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);// 놀이 내내 살아 있는 값: 반복문 밖에 let으로let total = 0;let bestRound = 0;let bestScore = -1;let streak = 0; // 지금 이어지는 깨끗한 판 수let longest = 0;let prevClean = false; // 바로 앞 판이 깨끗했는가const out = [];for (let r = 1; r <= n; r++) { const throws = lines[r].trim().split(/\s+/).map(Number).slice(1); // 이 판에서만 쓰는 값: 반복문 안에서 선언하면 판마다 새로 생긴다 let miss = 0; for (let i = 0; i < throws.length; i++) { if (throws[i] === 0) { miss = i + 1; // i는 이 for 안에서만 보이므로, 찾은 그 자리에서 적는다 break; } } let score = 0; for (const s of throws) score += s; if (prevClean) { score *= 2; // 여기서 let score를 또 쓰면 바깥 score와 다른 새 변수가 된다 } total += score; if (score > bestScore) { bestScore = score; bestRound = r; } const clean = miss === 0; if (clean) { streak++; if (streak > longest) longest = streak; } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 out.push(`${score} ${total} ${miss}`);}out.push(`${bestRound} ${bestScore} ${longest}`);console.log(out.join("\n"));
TypeScriptmain.ts · 47 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);// 놀이 내내 살아 있는 값: 반복문 밖에 let으로let total = 0;let bestRound = 0;let bestScore = -1;let streak = 0; // 지금 이어지는 깨끗한 판 수let longest = 0;let prevClean = false; // 바로 앞 판이 깨끗했는가const out: string[] = [];for (let r = 1; r <= n; r++) { const throws: number[] = lines[r].trim().split(/\s+/).map(Number).slice(1); // 이 판에서만 쓰는 값: 반복문 안에서 선언하면 판마다 새로 생긴다 let miss = 0; for (let i = 0; i < throws.length; i++) { if (throws[i] === 0) { miss = i + 1; // i는 이 for 안에서만 보이므로, 찾은 그 자리에서 적는다 break; } } let score = 0; for (const s of throws) score += s; if (prevClean) { score *= 2; // 여기서 let score를 또 쓰면 바깥 score와 다른 새 변수가 된다 } total += score; if (score > bestScore) { bestScore = score; bestRound = r; } const clean: boolean = miss === 0; if (clean) { streak++; if (streak > longest) longest = streak; } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 out.push(`${score} ${total} ${miss}`);}out.push(`${bestRound} ${bestScore} ${longest}`);console.log(out.join("\n"));
JavaMain.java · 53 lines
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine().trim()); // 놀이 내내 살아 있는 값: 반복문 밖에 선언한다 int total = 0; int bestRound = 0; int bestScore = -1; int streak = 0; // 지금 이어지는 깨끗한 판 수 int longest = 0; boolean prevClean = false; // 바로 앞 판이 깨끗했는가 StringBuilder out = new StringBuilder(); for (int r = 1; r <= n; r++) { StringTokenizer st = new StringTokenizer(br.readLine()); int k = Integer.parseInt(st.nextToken()); // 이 판에서만 쓰는 값: 반복문 안에 선언하면 판마다 새로 생긴다 int miss = 0; int score = 0; for (int i = 1; i <= k; i++) { int s = Integer.parseInt(st.nextToken()); score += s; if (s == 0 && miss == 0) miss = i; // i는 이 for 안에서만 보인다 } if (prevClean) { score *= 2; // 여기에 int score를 또 쓰면 Java는 컴파일 오류다 } total += score; if (score > bestScore) { bestScore = score; bestRound = r; } boolean clean = miss == 0; if (clean) { streak++; longest = Math.max(longest, streak); } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 out.append(score).append(' ').append(total).append(' ').append(miss).append('\n'); } out.append(bestRound).append(' ').append(bestScore).append(' ').append(longest).append('\n'); System.out.print(out); }}
C#Main.cs · 60 lines
using System;using System.Text;class Program{ static void Main() { int n = int.Parse(Console.ReadLine().Trim()); // 놀이 내내 살아 있는 값: 반복문 밖에 선언한다 int total = 0; int bestRound = 0; int bestScore = -1; int streak = 0; // 지금 이어지는 깨끗한 판 수 int longest = 0; bool prevClean = false; // 바로 앞 판이 깨끗했는가 var sb = new StringBuilder(); for (int r = 1; r <= n; r++) { string[] parts = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int k = int.Parse(parts[0]); // 이 판에서만 쓰는 값: 반복문 안에 선언하면 판마다 새로 생긴다 int miss = 0; int score = 0; for (int i = 1; i <= k; i++) { int s = int.Parse(parts[i]); score += s; if (s == 0 && miss == 0) miss = i; // i는 이 for 안에서만 보인다 } if (prevClean) { score *= 2; // 여기에 int score를 또 쓰면 C#은 컴파일 오류다 (CS0136) } total += score; if (score > bestScore) { bestScore = score; bestRound = r; } bool clean = miss == 0; if (clean) { streak++; longest = Math.Max(longest, streak); } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 sb.Append(score).Append(' ').Append(total).Append(' ').Append(miss).Append('\n'); } sb.Append(bestRound).Append(' ').Append(bestScore).Append(' ').Append(longest).Append('\n'); Console.Write(sb); }}
C++main.cpp · 51 lines
#include <algorithm>#include <iostream>int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n; std::cin >> n; // 놀이 내내 살아 있는 값: 반복문 밖에 선언하고 처음 값을 꼭 넣는다 int total = 0; int bestRound = 0; int bestScore = -1; int streak = 0; // 지금 이어지는 깨끗한 판 수 int longest = 0; bool prevClean = false; // 바로 앞 판이 깨끗했는가 for (int r = 1; r <= n; r++) { int k; std::cin >> k; // 이 판에서만 쓰는 값: 반복문 안에 선언하면 판마다 새로 시작한다 int miss = 0; int score = 0; for (int i = 1; i <= k; i++) { int s; std::cin >> s; score += s; if (s == 0 && miss == 0) miss = i; // i는 이 for 안에서만 보인다 } if (prevClean) { score *= 2; // 여기에 int score를 또 쓰면 바깥 score를 가리는 새 변수가 된다 } total += score; if (score > bestScore) { bestScore = score; bestRound = r; } const bool clean = miss == 0; if (clean) { streak++; longest = std::max(longest, streak); } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 std::cout << score << ' ' << total << ' ' << miss << '\n'; } std::cout << bestRound << ' ' << bestScore << ' ' << longest << '\n';}
Cmain.c · 49 lines
#include <stdio.h>int main(void) { int n; scanf("%d", &n); /* 놀이 내내 살아 있는 값: 반복문 밖에 선언하고 처음 값을 꼭 넣는다 */ int total = 0; int best_round = 0; int best_score = -1; int streak = 0; /* 지금 이어지는 깨끗한 판 수 */ int longest = 0; int prev_clean = 0; /* 바로 앞 판이 깨끗했는가 */ for (int r = 1; r <= n; r++) { int k; scanf("%d", &k); /* 이 판에서만 쓰는 값: 반복문 안에 선언하면 판마다 새로 시작한다 */ int miss = 0; int score = 0; for (int i = 1; i <= k; i++) { int s; scanf("%d", &s); score += s; if (s == 0 && miss == 0) miss = i; /* i는 이 for 안에서만 보인다 */ } if (prev_clean) { score *= 2; /* 여기에 int score를 또 쓰면 바깥 score를 가리는 새 변수가 된다 */ } total += score; if (score > best_score) { best_score = score; best_round = r; } int clean = miss == 0; if (clean) { streak++; if (streak > longest) longest = streak; } else { streak = 0; } prev_clean = clean; /* 이 판의 결과를 다 쓴 뒤에 넘긴다 */ printf("%d %d %d\n", score, total, miss); } printf("%d %d %d\n", best_round, best_score, longest); return 0;}
Craykonmain.cray · 50 lines
n = Console.ReadLine().ToNumber();// 놀이 내내 살아 있는 값: 반복문 앞에서 먼저 만든다total = 0;bestRound = 0;bestScore = -1;streak = 0; // 지금 이어지는 깨끗한 판 수longest = 0;prevClean = false; // 바로 앞 판이 깨끗했는가for (r = 1; r <= n; r++){ 줄 = Console.ReadNumbers(); // 이 판에서만 쓰는 값: 반복문 안에서 처음 만들면 판마다 새로 시작한다 miss = 0; score = 0; for (i = 1; i <= 줄[0]; i++) { score = score + 줄[i]; if (줄[i] == 0 && miss == 0) { miss = i; // i는 이 반복 안에서만 보인다 } } if (prevClean) { score = score * 2; // 이미 있는 이름에 넣으면 바깥 score가 바뀐다 } total = total + score; if (score > bestScore) { bestScore = score; bestRound = r; } clean = miss == 0; if (clean) { streak = streak + 1; longest = Mathf.Max(longest, streak); } else { streak = 0; } prevClean = clean; // 이 판의 결과를 다 쓴 뒤에 넘긴다 Console.WriteLine(score + " " + total + " " + miss);}Console.WriteLine(bestRound + " " + bestScore + " " + longest);