1012 The Best Rank (25 分)
题目链接
算法分析
优先队列+数组
分四种情况(C、M、E、A)压入优先队列中
然后把每个科目的排名存在各自的数组中
然后每种情况进行查询即可
测试点
测试点二:成绩相同
我虽然注意到了这一点,但是并没有过
原因在于:对于这样一组数据98 95 96 95 92
排名数据为:1 3 2 3 5
而不是:1 3 2 3 4
改过之后就满分了!
代码实现
#include<bits/stdc++.h>
using namespace std;
#define N 2005
#define T 1000000
char s[5] = {'E', 'M', 'C', 'A'};
typedef struct{
int Id;
int Mark_C, Mark_M, Mark_E, Mark_ave;
}STU;
STU stu[N];
priority_queue< int >fro_C, fro_M, fro_E, fro_ave;
int id[T];
int C[T], M[T], E[T], Ave[T];
void work(priority_queue< int > que, int *mp){
int last = -1, rank = 0, t = 0;;
while(!que.empty()){
++ t;
int x = que.top();
if(x != last) rank = t;
mp[x] = rank;
last = x;
que.pop();
}
}
char ans_char;
int Get_ans(int x){
int Min = 1e8, Min_t;
if(E[stu[id[x]].Mark_E] <= Min) Min = E[stu[id[x]].Mark_E], Min_t = 0;
if(M[stu[id[x]].Mark_M] <= Min) Min = M[stu[id[x]].Mark_M], Min_t = 1;
if(C[stu[id[x]].Mark_C] <= Min) Min = C[stu[id[x]].Mark_C], Min_t = 2;
if(Ave[stu[id[x]].Mark_ave] <= Min) Min = Ave[stu[id[x]].Mark_ave], Min_t = 3;
ans_char = s[Min_t];
return Min;
}
int main(){
int n, m, x;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i){
scanf("%d%d%d%d", &stu[i].Id, &stu[i].Mark_C, &stu[i].Mark_M, &stu[i].Mark_E);
id[stu[i].Id] = i;
stu[i].Mark_ave = (stu[i].Mark_C + stu[i].Mark_M + stu[i].Mark_E) / 3;
fro_C.push(stu[i].Mark_C);
fro_M.push(stu[i].Mark_M);
fro_E.push(stu[i].Mark_E);
fro_ave.push(stu[i].Mark_ave);
}
work(fro_C, C);
work(fro_M, M);
work(fro_E, E);
work(fro_ave, Ave);
for(int i = 1; i <= m; ++ i){
scanf("%d", &x);
if(!id[x]){
printf("N/A\n");
continue;
}
int ans = Get_ans(x);
printf("%d %c\n", ans, ans_char);
}
return 0;
}
学习柳诺
柳神的代码思路使用了sort排序
此外有一点我觉得比较值得采用:
这个题我用了单独的名称和数组,所以看起来就会不太简洁
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
struct node {
int id, best;
int score[4], rank[4];
}stu[2005];
int exist[1000000], flag = -1;
bool cmp1(node a, node b) {return a.score[flag] > b.score[flag];}
int main() {
int n, m, id;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%d %d %d %d", &stu[i].id, &stu[i].score[1], &stu[i].score[2], &stu[i].score[3]);
stu[i].score[0] = (stu[i].score[1] + stu[i].score[2] + stu[i].score[3]) / 3.0 + 0.5;
}
for(flag = 0; flag <= 3; flag++) {
sort(stu, stu + n, cmp1);
stu[0].rank[flag] = 1;
for(int i = 1; i < n; i++) {
stu[i].rank[flag] = i + 1;
if(stu[i].score[flag] == stu[i-1].score[flag])
stu[i].rank[flag] = stu[i-1].rank[flag];
}
}
for(int i = 0; i < n; i++) {
exist[stu[i].id] = i + 1;
stu[i].best = 0;
int minn = stu[i].rank[0];
for(int j = 1; j <= 3; j++) {
if(stu[i].rank[j] < minn) {
minn = stu[i].rank[j];
stu[i].best = j;
}
}
}
char c[5] = {'A', 'C', 'M', 'E'};
for(int i = 0; i < m; i++) {
scanf("%d", &id);
int temp = exist[id];
if(temp) {
int best = stu[temp-1].best;
printf("%d %c\n", stu[temp-1].rank[best], c[best]);
} else {
printf("N/A\n");
}
}
return 0;
}