1 ≤ k ≤ 20,1 ≤ n ≤ 5,000。 候选人名互不相同,由 1~10 个小写英文字母组成。 学号由小写英文字母和数字组成,1~8 个字符。 票上的候选人名一定是候选人之一
输出
k 行(候选人名、票数),然后一行(学生人数)
样例 1 · stdin
3
mina joon hana
5
s1 mina
s2 joon
s1 hana
s3 joon
s2 mina
stdout
mina 1
joon 1
hana 1
3
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
把每个学生当前算的票放在字典里,新票来了就覆盖那个值。 陷阱在于很多语言里“覆盖”和“不覆盖”的写法很像。 Python d[k] = v、JS/TS map.set(k, v)、Craykon d[k] = v 会替换原来的值。 Java put 也会覆盖,但 putIfAbsent 只在键不存在时才放入。 C# 索引器 d[k] = v 会覆盖,但 d.Add(k, v) 遇到已有的键会抛出 ArgumentException。 C++ m[k] = v 会覆盖,但 m.insert({k, v}) 和 emplace 在键已存在时什么也不做,留下的是第一票。 先全部读完,再只遍历字典的值按候选人计数,就不用担心改票时忘了从原候选人那里减 1。 学号保持为字符串。 在 JS 里用 Number 转换,"1" 和 "01" 会变成同一个学生。 C 没有字典,要把学号记在数组里,用 strcmp 从前往后找。
Pythonmain.py · 13 行
k = int(input())cands = input().split()n = int(input())vote = {} # 학생 번호 → 지금 센 표for _ in range(n): voter, cand = input().split() vote[voter] = cand # 있던 표는 덮어쓴다count = {c: 0 for c in cands}for cand in vote.values(): count[cand] += 1for c in cands: print(c, count[c])print(len(vote))
JavaScriptmain.js · 18 行
const tok = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);let p = 0;const k = Number(tok[p++]);const cands = tok.slice(p, p + k);p += k;const n = Number(tok[p++]);// 학생 번호는 문자열 그대로 둔다("01"과 "1"은 다른 학생)const vote = new Map();for (let i = 0; i < n; i++) { const voter = tok[p++]; const cand = tok[p++]; vote.set(voter, cand); // set은 있던 값을 덮어쓴다}const count = new Map(cands.map((c) => [c, 0]));for (const cand of vote.values()) count.set(cand, count.get(cand) + 1);const out = cands.map((c) => `${c} ${count.get(c)}`);out.push(String(vote.size));console.log(out.join("\n"));
TypeScriptmain.ts · 18 行
import { readFileSync } from "node:fs";const tok: string[] = readFileSync(0, "utf8").trim().split(/\s+/);let p = 0;const k: number = Number(tok[p++]);const cands: string[] = tok.slice(p, p + k);p += k;const n: number = Number(tok[p++]);const vote = new Map<string, string>();for (let i = 0; i < n; i++) { const voter: string = tok[p++]; const cand: string = tok[p++]; vote.set(voter, cand); // set은 있던 값을 덮어쓴다}const count = new Map<string, number>(cands.map((c): [string, number] => [c, 0]));for (const cand of vote.values()) count.set(cand, (count.get(cand) ?? 0) + 1);const out: string[] = cands.map((c) => `${c} ${count.get(c)}`);out.push(String(vote.size));console.log(out.join("\n"));
JavaMain.java · 28 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;import java.util.StringTokenizer;public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int k = Integer.parseInt(br.readLine().trim()); String[] cands = br.readLine().trim().split("\\s+"); int n = Integer.parseInt(br.readLine().trim()); Map<String, String> vote = new HashMap<>(); for (int i = 0; i < n; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); String voter = st.nextToken(); String cand = st.nextToken(); vote.put(voter, cand); // put은 덮어쓴다(putIfAbsent는 처음 값을 지킨다) } Map<String, Integer> count = new HashMap<>(); for (String c : cands) count.put(c, 0); for (String cand : vote.values()) count.merge(cand, 1, Integer::sum); StringBuilder out = new StringBuilder(); for (String c : cands) out.append(c).append(' ').append(count.get(c)).append('\n'); out.append(vote.size()).append('\n'); System.out.print(out); }}
C#Main.cs · 27 行
using System;using System.Collections.Generic;using System.Text;class Program{ static void Main() { int k = int.Parse(Console.ReadLine().Trim()); string[] cands = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(Console.ReadLine().Trim()); var vote = new Dictionary<string, string>(); for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); // 인덱서 대입은 덮어쓴다. Add는 이미 있는 열쇠에서 예외를 던진다 vote[p[0]] = p[1]; } var count = new Dictionary<string, int>(); foreach (string c in cands) count[c] = 0; foreach (string cand in vote.Values) count[cand]++; var sb = new StringBuilder(); foreach (string c in cands) sb.Append(c).Append(' ').Append(count[c]).Append('\n'); sb.Append(vote.Count).Append('\n'); Console.Write(sb); }}
C++main.cpp · 23 行
#include <iostream>#include <string>#include <unordered_map>#include <vector>int main() { std::ios::sync_with_stdio(false); int k, n; std::cin >> k; std::vector<std::string> cands(k); for (auto& c : cands) std::cin >> c; std::cin >> n; std::unordered_map<std::string, std::string> vote; for (int i = 0; i < n; i++) { std::string voter, cand; std::cin >> voter >> cand; vote[voter] = cand; // operator[]는 덮어쓴다. insert·emplace는 있던 값을 그대로 둔다 } std::unordered_map<std::string, int> count; for (const auto& [voter, cand] : vote) count[cand]++; for (const auto& c : cands) std::cout << c << ' ' << count[c] << '\n'; std::cout << vote.size() << '\n';}
Cmain.c · 32 行
#include <stdio.h>#include <string.h>/* C에는 사전이 없어서, 학생 번호와 그 학생의 표(후보 번호)를 배열에 적고 앞에서부터 찾는다 */static char voters[5000][9];static int choice[5000];static char cands[20][11];int main(void) { int k, n, m = 0; scanf("%d", &k); for (int i = 0; i < k; i++) scanf("%10s", cands[i]); scanf("%d", &n); for (int i = 0; i < n; i++) { char voter[16], cand[16]; scanf("%15s %15s", voter, cand); int c = 0; while (strcmp(cands[c], cand) != 0) c++; int j = 0; while (j < m && strcmp(voters[j], voter) != 0) j++; if (j == m) { strcpy(voters[m], voter); m++; } choice[j] = c; /* 있던 표는 덮어쓴다 */ } int count[20] = {0}; for (int j = 0; j < m; j++) count[choice[j]]++; for (int i = 0; i < k; i++) printf("%s %d\n", cands[i], count[i]); printf("%d\n", m); return 0;}
Craykonmain.cray · 24 行
k = 控制台.读行().转数字();cands = 控制台.读行().去空白().分割(" ");n = 控制台.读行().转数字();vote = 字典();循环 (i = 0; i < n; i++){ p = 控制台.读行().去空白().分割(" "); // 같은 열쇠에 다시 넣으면 있던 표를 덮어쓴다 vote[p[0]] = p[1];}count = 字典();遍历 (c 在 cands){ count[c] = 0;}遍历 (cand 在 vote.值列表){ count[cand] = count[cand] + 1;}遍历 (c 在 cands){ 控制台.输出(c + " " + count[c]);}控制台.输出(vote.数量);