OD統一考試(C卷)
分值: 100分
題解: Java / Python / C++
題目描述
幼兒園組織活動,老師布置了一個任務:
每個小朋友去了解與自己同一個小區的小朋友還有幾個。
我們將這些數量匯總到數組 garden 中。
請根據這些小朋友給出的信息,計算班級小朋友至少來自幾個小區?
輸入描述
輸入:garden[] = {2, 2, 3}
說明:
- garden 數組長度最大為 999
- 每個小區的小朋友數量最多 1000 人,也就是 garden[i] 的范圍為 [0, 999]
輸出描述
輸出:7
示例1
輸入:
2 2 3輸出:
7說明:
第一個小朋友反饋有兩個小朋友和自己同一小區,即此小區有3個小朋友。
第二個小朋友反饋有兩個小朋友和自己同一小區,即此小區有3個小朋友。
這兩個小朋友,可能是同一小區的,且此小區的小朋友只有3個人。
第三個小區反饋還有3個小朋友與自己同一小區,則這些小朋友只能是另外一個小區的。這個小區有4個小朋友。
題解
本題出的有誤,輸出其實是至少的小朋友數量,而不是班級小朋友至少來自幾個小區。
通過例子來說明:
garden = {2,2} // 可能來自同一個小區, 學生人數 = 1(自己) + 2(其他小朋友個數)
graden = {2,2,2} // 可能來自同一個小區, 學生人數 = 1(自己) + 2(其他小朋友個數)
graden = {2,2,2,2} // 不可能來自同一個小區, 至少來自 2 個小區, 學生人數 = 2 * (1 + 2)
假如有 v 個小朋友說來自其他小區小朋友有 k 個:
- 則至少有小區個數: v / (k + 1) 向上取整 == (v + k) / (k + 1)
- 則每個小區的人數: 1(自己) + k(其他小朋友人數)
- 則至少小朋友數: (v + k) / (k + 1) * ( k + 1)
根據以上的總結, 就可以對小朋友給出的數據進行統計, 統計完后再根據統計數據計算出總的學生人數。
Java
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);Map<Integer, Integer> cnt = new HashMap<>();// 讀取輸入并統計數字出現次數while (scanner.hasNextInt()) {int t = scanner.nextInt();cnt.put(t, cnt.getOrDefault(t, 0) + 1);}int tot = 0;// 遍歷統計結果for (Map.Entry<Integer, Integer> entry : cnt.entrySet()) {int k = entry.getKey();int v = entry.getValue();// 計算小區個數,向上取整int group = (v + k) / (k + 1);// 計算總人數tot += group * (k + 1);}System.out.println(tot);}
}
Python
from collections import defaultdictdef main():cnt = defaultdict(int) # 使用 defaultdict 初始化計數字典tot = 0# 統計每個數出現的次數for t in list(map(int, input().split())):cnt[t] += 1# 遍歷計數字典,計算總人數for k, v in cnt.items():group = (v + k) // (k + 1) # 小區個數,向上取整tot += group * (k + 1) # 每個小區人數(k + 1)print(tot)if __name__ == "__main__":main()
C++
以下是將 Java 代碼翻譯成 Python 的版本,并在關鍵代碼上添加注釋:
#include <bits/stdc++.h>
using namespace std;int main()
{unordered_map<int, int> cnt;int t;while (cin >> t) {cnt[t]++;}int tot;for (const auto& it : cnt) {int k = it.first, v = it.second;int group = (v + k) / (k + 1); // 小區個數,向上取整tot += group * (k + 1); // 每個小區人數(k + 1)}cout << tot << endl;return 0;
}
🙏整理題解不易, 如果有幫助到您,請給點個贊 ???? 和收藏 ?,讓更多的人看到。🙏🙏🙏