主页
搜索
最近更新
数据统计
申请密钥
批量保存
开发版网站(新前端)
系统公告
1
/
1
请查看完所有公告
题解:P11185 奖牌排序
最后更新于 2025-08-28 09:00:06
作者
2huk
分类
题解
题解
P11185
复制 Markdown
查看原文
转到新前端
删除文章
更新内容
不妨只考虑对金牌数排序的情况。按银牌/铜牌数量排序的情况类似。 显然如果有 $j$ 个小朋友的金牌数**严格大于**小朋友 $j$ 的金牌数,那么他的排名一定不小于 $j+1$。 而且题目告诉了你「如果自己和别的小朋友并列,那么他可以把自己写在最前面」。所以小朋友 $j$ 的排名可以取 $j +1$ 且这样最优。 于是问题变成了如何对于每个小朋友 $i$ 都计算出有多少小朋友的金牌数严格大于自己的。 首先将所有小朋友按照金牌数量降序排序。在枚举 $i$ 的同时,维护 $j$ 表示最后一个金牌数严格大于小朋友 $i$ 的位置。那么 $j$ 同时也一定是第一个与 $i$ 相同的位置。所以每次判断一下若 $a_i \ne a_j$ 则更新 $j \gets i$ 即可。 ```cpp #include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int n; struct Child { int a, b, c, id; }p[N]; int res[N]; void chkmin(int &x, int y) { x = min(x, y); } signed main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> n; for (int i = 1; i <= n; ++ i ) { cin >> p[i].a >> p[i].b >> p[i].c; p[i].id = i; } memset(res, 0x3f, sizeof res); sort(p + 1, p + n + 1, [&](Child x, Child y) { return x.a > y.a; }); for (int i = 1, j = 1; i <= n; ++ i ) { if (p[i].a != p[j].a) j = i; chkmin(res[p[i].id], j); } sort(p + 1, p + n + 1, [&](Child x, Child y) { return x.b > y.b; }); for (int i = 1, j = 1; i <= n; ++ i ) { if (p[i].b != p[j].b) j = i; chkmin(res[p[i].id], j); } sort(p + 1, p + n + 1, [&](Child x, Child y) { return x.c > y.c; }); for (int i = 1, j = 1; i <= n; ++ i ) { if (p[i].c != p[j].c) j = i; chkmin(res[p[i].id], j); } for (int i = 1; i <= n; ++ i ) cout << res[i] << '\n'; return 0; } ```
正在渲染内容...
点赞
3
收藏
0