用 map 把名字映射为下标,按送礼顺序模拟:人均 m/cnt、余数自留,最后按读入顺序输出每人净额。
OJ: roj
题目 ID: 2001
难度:入门
标签:入门模拟字符串哈希表python
创建: 2026-10-01 02:15
更新: 2026-10-06 08:59
题目描述
思路
把名字用 map<string,int> 映射成下标,维护一个钱数数组。逐条读取送礼记录:若
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-01 02:15
# update_at: 2026-10-01 02:18
import sys
def solve() -> None:
data = iter(sys.stdin.buffer.read().split())
n = int(next(data))
names = [next(data).decode() for _ in range(n)] # 题面第 2 ~ n+1 行:n 个名字
index = {name: i for i, name in enumerate(names)} # 名字 → 编号,查人 O(1)
money = [0] * n
for giver in data: # 每组记录以送钱人的名字开头,读到文件末尾
amount, cnt = int(next(data)), int(next(data))
share, left = divmod(amount, cnt) if cnt else (0, 0) # cnt 为 0 时不做除法
money[index[giver.decode()]] += left - amount # 送出的钱扣掉,除不尽的余数自己留下
for _ in range(cnt):
money[index[next(data).decode()]] += share # 每位接收者拿到平分的 share
print('\n'.join(f"{name} {value}" for name, value in zip(names, money)))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 08:59
* update_at: 2026-10-06 08:59
*/
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef long long ll;
const int MAXN = 25; // 人数上限,n <= 20
string names[MAXN]; // 按输入顺序保存名字
map<string, int> id; // 名字 -> 下标
ll money[MAXN]; // 每个人的最终钱数
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> names[i];
id[names[i]] = i;
}
string giver;
while (cin >> giver) { // 每条记录以送钱人名字开头,读到 EOF 结束
ll m;
int cnt;
cin >> m >> cnt;
ll share = 0, left = 0;
if (cnt != 0) { // cnt 为 0 时不做除法
share = m / cnt;
left = m % cnt;
}
int g = id[giver];
money[g] += left - m; // 送钱人扣掉真正分出去的部分,余数自留
for (int i = 0; i < cnt; i++) {
string receiver;
cin >> receiver;
money[id[receiver]] += share;
}
}
for (int i = 0; i < n; i++) {
cout << names[i] << " " << money[i] << "\n";
}
return 0;
}