每行 A B 即 v_A += 1、v_B -= 1,三个桶逐行累加净欠账,最后按 D G Z 输出,O(n) 时间 O(1) 额外空间。
OJ: roj
题目 ID: 8013
难度:入门
标签:入门桶python
创建: 2026-10-02 16:34
更新: 2026-10-06 16:51
题目描述
输入 D、G、Z),表示 D G Z 顺序给出每个人的净额:正数表示欠别人几顿,0 表示不欠不被欠,负数表示借给别人几顿。
思路
用三个桶记录每个人的净额:每读一行 A B,就执行 v[A] += 1、v[B] -= 1,全部读完后按 D G Z 顺序输出三桶即可。
参考代码
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-02 16:37
# update_at: 2026-10-02 16:37
import sys
def solve() -> None:
data = iter(sys.stdin.buffer.read().split())
day_count = int(next(data)) # 记账天数 n
debt = {who: 0 for who in "DGZ"} # 净额桶:正 = 欠别人几顿,负 = 借给别人几顿
for _ in range(day_count): # 每天一条记录:欠账人 欠给 被欠人
debtor, creditor = next(data).decode(), next(data).decode()
debt[debtor] += 1 # 欠账人净额 +1(欠了别人一顿)
debt[creditor] -= 1 # 被欠人净额 -1(借给别人一顿)
# 固定按 D G Z 三行输出,桶里没有出现过的人保持 0
print("\n".join(f"{who} {debt[who]}" for who in "DGZ"))
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 16:51
* update_at: 2026-10-06 16:51
*/
#include <iostream>
using namespace std;
typedef long long ll;
ll v[3]; // 三个桶:0=D, 1=G, 2=Z,净额:正=欠别人,负=借给别人
// 把字母 D/G/Z 映射成下标 0/1/2
ll idx(char c) {
if (c == 'D') return 0;
if (c == 'G') return 1;
return 2;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll n;
char a, b;
cin >> n;
for (ll i = 1; i <= n; i++) {
cin >> a >> b;
v[idx(a)]++; // 欠账人净额 +1
v[idx(b)]--; // 被欠人净额 -1
}
cout << "D " << v[0] << "\n";
cout << "G " << v[1] << "\n";
cout << "Z " << v[2] << "\n";
return 0;
}