原题地址
https://pintia.cn/problem-sets/1268384564738605056/problems/1291317697694580737
解题思路
有点麻烦的一道题,搞了我1个小时…
主要思路就是用结构体数组来存所有的信息,刚开始数组下标与id相对应(这样比较好更新值),然后用一个bool数组记录可以输出的元素(可以输出的条件:提交的分数>=0),之后进行
注意事项
1.一开始在结构体定义的时候写 int pro[5] = {-1}
,这样发现只有第一个元素被赋值为-1
,然后想起来只有写0的时候才是给整个数组赋值为0
。因此之后采用修改构造函数的方式来赋值。
2.如果有提交但是编译未通过,该题的分数输出为0
而不是-
。(进行这一步的时候要判断之前是不是-1
,否则之前分数大于等于0
的话无需更新)
参考代码
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 1e4 + 10;
struct stu{
int id, fullN = 0, score = 0;
int pro[5];
//stu() {};
stu() {
memset(pro, -1, sizeof(pro)); //重新定义构造函数
}
}stus[maxn];
bool cmp(stu a, stu b) {
if (a.score != b.score) return a.score > b.score;
else if (a.fullN != b.fullN) return a.fullN > b.fullN;
else return a.id < b.id;
}
bool has[maxn];
int main() {
/* for (int i = 0; i < maxn; i++)
memset(stus[i].pro, -1, sizeof(stus[i].pro));*/
int n, k, m;
int p[5];
scanf("%d%d%d", &n, &k, &m);
for (int i = 0; i < k; i++) {
scanf("%d", &p[i]);
}
int id, num, s;
for (int t = 0; t < m; t++) {
scanf("%d%d%d", &id, &num, &s);
num--; //存储的num从0开始
if (s >= 0) {
has[id] = true; //若有编译成功的,直接标记
}
stus[id].id = id;
int pre = stus[id].pro[num];
if (s == -1 && pre == -1) //若编译失败且之前没有提交过,则分数变为0
stus[id].pro[num] = 0;
if (s > pre) { //若当前s比之前的大,才要更新
if (pre >= 0) stus[id].score += s - pre;
else stus[id].score += s;
stus[id].pro[num] = s;
}
if (s == p[num] && pre != s) //若当前的是满分,且之前不是,说明是首次满分
stus[id].fullN++;
/* cout << "第" << t << "次:";
printf("%05d %d 个数:%d", stus[id].id, stus[id].score, stus[id].fullN);
for (int j = 0; j < k; j++) printf(" %d", stus[id].pro[j]);
printf("\n"); */
}
vector<stu> ans;
for (int i = 0; i < maxn; i++) {
if (has[i]) ans.pb(stus[i]);
}
sort(ans.begin(), ans.end(), cmp);
int pre, rank, now;
for (int i = 0; i < ans.size(); i++) {
now = ans[i].score;
//输出rank要注意~
if (i == 0) { //首位分开处理
rank = 1;
} else{
if (now < pre) rank = i + 1; //如果当前的总分小,说明rank值要变化了,即为i+1
}
pre = now; //保存当前的总分,与下一个比较
printf("%d %05d %d", rank, ans[i].id, ans[i].score);
for (int j = 0; j < k; j++) {
int pg = ans[i].pro[j];
if (pg >= 0) printf(" %d", ans[i].pro[j]);
else printf(" -"); //值为-1的即是没有提交过的
}
printf("\n");
}
return 0;
}