一、概述
写一个模仿PAT的算法计算总分的程序。
挺麻烦的,和考场问题差不多。总分排序加上各人各题排序。
两个排序之后还有几个坑:
这样的人是不会输出的:没有过submit的人,sub了但是没有编译通过的人。
为了把这样的人摘出去,我们需要使用两个旗语,分别计算sub数和编译成功数。
都不为0才输出。
第二个坑是只要有sub,那么即使编译未通过,该题分数也是0而不是-,这一点要注意。
最后一个检查点有这样一个坑:如果之前编译通过了,之后编译未通过,那么分数不会变。虽然现实中出现这种蛋疼的概率很小,但还是要考虑。我就是没考虑这点,粗暴的遇到sub的-1就直接将该题分数改为0,因此最后一个检查点卡了一下。
二、分析
分别用两个结构体存储sub和user。如下:
struct submission
{
int userID;
int problemID;
int partialscore;
}sub[100010];
struct User
{
int s[5] = { -1,-1,-1,-1,-1 };
int sum = 0;
int perfect = 0;
int subnum = 0;
int passnum = 0;
int final = 0;
int userID;
}user[10010];
user的单项分数赋初值为-1有利于减少输出时的判断。
共需排序两次,一次是排序sub,按ID优先,题目其次,分数再其次排序;一次是排序user,按总分优先,完美数其次,id再其次排序。如下:
bool cmp(submission a, submission b)
{
if (a.userID != b.userID)
return a.userID < b.userID;
else if (a.problemID != b.problemID)
return a.problemID < b.problemID;
else
return a.partialscore > b.partialscore;
}
bool cmpfinal(User a, User b)
{
if (a.sum != b.sum)
return a.sum > b.sum;
else if (a.perfect != b.perfect)
return a.perfect > b.perfect;
else
return a.userID<b.userID;
}
先存储输入数据,然后进行第一次排序和处理。
sort(sub, sub + M, cmp);
for (i = 0; i < M; i++)
{
if (sub[i].partialscore == -1 && user[sub[i].userID].s[sub[i].problemID - 1] == -1)//这里是最后一个检查点的坑
{
user[sub[i].userID].s[sub[i].problemID - 1] = 0;//sub的-1和位编译通过不一样
user[sub[i].userID].subnum++;
}
if (sub[i].partialscore > user[sub[i].userID].s[sub[i].problemID - 1])
{
user[sub[i].userID].s[sub[i].problemID - 1] = sub[i].partialscore;
user[sub[i].userID].subnum++;
user[sub[i].userID].passnum++;
if (user[sub[i].userID].s[sub[i].problemID - 1] == Smax[sub[i].problemID - 1])
user[sub[i].userID].perfect++;
}
}
for (i = 1; i < N + 1; i++)
{
user[i].userID = i;
for (j = 0; j < K; j++)
{
if (user[i].s[j] >= 0)
user[i].sum += user[i].s[j];
}
}
然后是第二次排序和排总名次。
sort(user + 1, user + N + 1, cmpfinal);
user[1].final = 1;
for (i = 2; i < N + 1; i++)
{
if (user[i].sum == user[i - 1].sum)
user[i].final = user[i - 1].final;
else
user[i].final = i;
}
最后输出即可。
三、总结
用了两个结构体之后代码有时候会变得好长,要注意分析。
PS:代码如下:
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct submission
{
int userID;
int problemID;
int partialscore;
}sub[100010];
struct User
{
int s[5] = { -1,-1,-1,-1,-1 };
int sum = 0;
int perfect = 0;
int subnum = 0;
int passnum = 0;
int final = 0;
int userID;
}user[10010];
bool cmp(submission a, submission b)
{
if (a.userID != b.userID)
return a.userID < b.userID;
else if (a.problemID != b.problemID)
return a.problemID < b.problemID;
else
return a.partialscore > b.partialscore;
}
bool cmpfinal(User a, User b)
{
if (a.sum != b.sum)
return a.sum > b.sum;
else if (a.perfect != b.perfect)
return a.perfect > b.perfect;
else
return a.userID<b.userID;
}
int main()
{
int N, K, M;//用户数,题目数,提交次数
scanf("%d %d %d", &N, &K, &M);
int Smax[5] = { 0 };
int i, j;
for (i = 0; i < K; i++)
scanf("%d", &Smax[i]);
for (i = 0; i < M; i++)
{
scanf("%d %d %d", &sub[i].userID, &sub[i].problemID, &sub[i].partialscore);
}
sort(sub, sub + M, cmp);
for (i = 0; i < M; i++)
{
if (sub[i].partialscore == -1 && user[sub[i].userID].s[sub[i].problemID - 1] == -1)
{
user[sub[i].userID].s[sub[i].problemID - 1] = 0;
user[sub[i].userID].subnum++;
}
if (sub[i].partialscore > user[sub[i].userID].s[sub[i].problemID - 1])
{
user[sub[i].userID].s[sub[i].problemID - 1] = sub[i].partialscore;
user[sub[i].userID].subnum++;
user[sub[i].userID].passnum++;
if (user[sub[i].userID].s[sub[i].problemID - 1] == Smax[sub[i].problemID - 1])
user[sub[i].userID].perfect++;
}
}
for (i = 1; i < N + 1; i++)
{
user[i].userID = i;
for (j = 0; j < K; j++)
{
if (user[i].s[j] >= 0)
user[i].sum += user[i].s[j];
}
}
sort(user + 1, user + N + 1, cmpfinal);
user[1].final = 1;
for (i = 2; i < N + 1; i++)
{
if (user[i].sum == user[i - 1].sum)
user[i].final = user[i - 1].final;
else
user[i].final = i;
}
for (i = 1; i < N + 1; i++)
{
if (user[i].passnum != 0 && user[i].subnum != 0)
{
printf("%d %05d %d", user[i].final, user[i].userID, user[i].sum);
for (j = 0; j < K; j++)
{
if (user[i].s[j] != -1)
printf(" %d", user[i].s[j]);
else
printf(" -");
}
printf("\n");
}
}
}