一、题目要求
有N个学生,某次考试有K个问题,给出M条成绩记录,要求根据记录统计输出排名名单。
不加入名单的条件:K个问题均未提交或未通过编译。
成绩输出格式:未提交输出’-’,提交且编译未通过成绩为零,其他成绩正常输出。
二、思路
设考生N位,科目K门:
1、构造数组
(1)flag[N + 1], 若考生i存在一门科目成绩有效即在区间[0, full_mark]内,则flag[i] = 1可以参与排名。
(2)score[N + 1][K + 1], score[i][j] = x指代考生i第j门科目成绩为x。特别的:未提交存储为-1,编译未通过存储为0。
2、数据处理
(1)构造结构体:
struct node
{
int id, cnt, sum;//cnt为满分科目数,sum为总成绩
};
(2)统计所有flag[i] == 1的考生i,统计id, cnt, sum等信息,加入数组ans
(3)排名输出
for( int i = 0, r; i < ans.size(); ++i )
{
if( !i || ans[i].sum != ans[i - 1].sum )//生成排名
r = i + 1;
printf("%d %05d %d", r, ans[i].id, ans[i].sum);
for( int j = 1; j <= K; ++j )
if( score[ans[i].id][j] == -1 )//成绩为-1为未提交,输出'-'
printf(" -");
else printf(" %d", score[ans[i].id][j]);
printf("\n");
}
三、代码
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct node
{
int id, cnt, sum;
};
int cmp( node a, node b )
{
if( a.sum != b.sum )
return a.sum > b.sum;
else if( a.cnt != b.cnt )
return a.cnt > b.cnt;
return a.id < b.id;
}
int main()
{
int N, K, M;
scanf("%d %d %d", &N, &K, &M);
vector<int> flag(N + 1, 0), full(K + 1);
vector<vector<int>> score(N + 1, vector<int>(K + 1, -1));
vector<node> ans;
for( int i = 1; i <= K; ++i )
scanf("%d", &full[i]);
for( int i = 0, id, course, val; i < M; ++i )
{
scanf("%d %d %d", &id, &course, &val);
score[id][course] = max(score[id][course], val == -1 ? 0:val);
if( val != -1 )
flag[id] = 1;
}
for( int i = 1; i <= N; ++i )
if( flag[i] )
{
node temp = {i, 0, 0};
for( int j = 1; j <= K; ++j )
{
if( score[i][j] != -1 )
temp.sum += score[i][j];
if( score[i][j] == full[j] )
++temp.cnt;
}
ans.push_back(temp);
}
sort( ans.begin(), ans.end(), cmp );
for( int i = 0, r; i < ans.size(); ++i )
{
if( !i || ans[i].sum != ans[i - 1].sum )
r = i + 1;
printf("%d %05d %d", r, ans[i].id, ans[i].sum);
for( int j = 1; j <= K; ++j )
if( score[ans[i].id][j] == -1 )
printf(" -");
else printf(" %d", score[ans[i].id][j]);
printf("\n");
}
}