PAT_A1075
PAT甲级1075.
目录
A1075
题目
样例
输入:
7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0
输出:
1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -
思路和坑点
对于每一个学生使用结构体存储,对于其成绩,使用数组表示并初始化为-2,表示未提交过,-1表示未通过编译。依次读取成绩的提交记录,每次如果有更高的成绩,则更新成绩。然后遍历并统计计算学生的各项参数,最后排序并输出。
主要的难点在于数据的处理:成绩的更新,统计和输出、不需要输出的删选、排序规则。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
int id,total=0,tag=0,cnt=0; //id,total总分,tag为是否输出的标记,1表示需要输出,cnt为完美解题计数
int score[6]; //成绩记录数组,初始化为-2,表示未提交过
node(){
for(int i=1;i<=5;i++)
score[i]=-2;
}
}Node;
vector<Node> v; //存放数据
vector<int> sid; //用于下标排序
bool cmp(int i,int j){ //排序函数
if(v[i].tag!=v[j].tag) return v[i].tag>v[j].tag; //需要输出的在前
else if(v[i].total!=v[j].total) return v[i].total>v[j].total; //总成绩从高到底
else if(v[i].cnt!=v[j].cnt) return v[i].cnt>v[j].cnt; //cnt从高到底
else return v[i].id<v[j].id; //id从低到高
}
int main(void){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
int n,m,k;
scanf("%d%d%d",&n,&k,&m); //读入数据,并初始化每一个容器的大小
vector<int> p(k+1); //记录每题的分值
v.resize(n+1); sid.resize(n+1);
for(int i=1;i<=k;i++) //读入各题分值
scanf("%d",&p[i]);
for(int i=0;i<m;i++){ //读入每次提交
int id,index,s;
scanf("%d%d%d",&id,&index,&s);
if(s>v[id].score[index]) //如果成绩更高则更新
v[id].score[index]=s;
}
for(int i=1;i<=n;i++){ //处理并统计每位学生的成绩信息
sid[i]=i; //初始化下标排序数组
v[i].id=i; //初始化每一个学生的id
for(int j=1;j<=k;j++){
if(v[i].score[j]>=0){ //如果有提交过则tag标记为1
v[i].tag=1;
v[i].total+=v[i].score[j]; //成绩总分累加
if(v[i].score[j]==p[j]) //如果完美解题,cnt计数加一
v[i].cnt++;
}
}
}
sort(sid.begin()+1,sid.end(),cmp); //排序
int rank,pre; //rank为排名 ,pre用于记录前一个记录的下标
for(int i=1;i<=n;i++){
int l=sid[i]; //读取当前的学生下标
if(v[l].tag==0) break; //如果不需要输出,则返回(因为排完序之后,不需要输出的都在后边)
if(i==1) rank=1; //第一个rank为1
else if(v[l].total!=v[pre].total) rank=i; //如果总成绩和前一个人不同,rank=i,否则和前一个人同排名
printf("%d %05d %d",rank,v[l].id,v[l].total); //输出结果
for(int j=1;j<=k;j++){ //输入每一题的成绩
switch(v[l].score[j]){
case -2: printf(" -");break; //未提交为 -
case -1: printf(" 0");break; //未通过编译为0
default: printf(" %d",v[l].score[j]);break;
}
}
putchar('\n');
pre=l; //更新pre
}
return 0;
}