PAT A1025 PAT Ranking
思路:每组输入的同时进行组内排序,输入完成后总排序。首先设置sort排序后第一个人的名次1,若后一个人与前一个人的成绩相等,则排名等于前一个人的排名,否则等于原本所在数组的序号+1;
问题:
1、sort函数的使用:
#include<algorithm>
using namespace std;
...
Student a,b;
sort(a,b,comp);//比较函数可缺省
...
bool comp(Student a, Student b)
{
if(a.score !=s1.score)return a.score>a.score;//若分数不同,按分数降序排列
else return strcmp(a.name,b.name)<0;//若分数相同,按姓名升序排列
}
2、字符的大小比较:
strcmp(a.name,b.name)<0//不能直接是a.name<b.name
3、仅考虑两组样例,应该用多组。在计算每一组的起始地址时不要忘记加上前几组的大小。
4、本题中学号长度13,以字符串存放:看到题目要求10的9次方以内,或者是32位整数,用Int型存放;如果是10的18次方以内,或者是64位整数,用long long 存放。
bool cmp(Stu s,Stu s1)
{
//if(s.score==s1.score)return strcmp(s.num,s.num)<0; 不能正确排序?????
//else return s.score>s1.score;
if(s.score !=s1.score)return s.score>s1.score;
else return strcmp(s.num,s1.num)<0;
}
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Stu
{
char num[15];
int score;
int k0;
int rankp;
int ranks;
};
bool cmp(Stu s,Stu s1)
{
if(s.score !=s1.score)return s.score>s1.score;
else return strcmp(s.num,s1.num)<0;
}
int main()
{
Stu stu[30000];
int n,times=0,t;
int k[110]={0};
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&k[i]); //每组人数
t=k[i];
while(t--)
{
scanf("%s%d",stu[times].num,&stu[times].score);
stu[times].k0=i;
times++;
}
sort(stu+times-k[i],stu+times,cmp); //组内排序
stu[times-k[i]].rankp=1; //组内第一个人
for(int q=times-k[i]+1;q<times;q++)
{
if(stu[q].score==stu[q-1].score)stu[q].rankp=stu[q-1].rankp;
else stu[q].rankp=q-times+k[i]+1;
}
}
sort(stu,stu+times,cmp); //整体排序
stu[0].ranks=1;
for(int q=1;q<times;q++)
{
if(stu[q].score==stu[q-1].score)stu[q].ranks=stu[q-1].ranks;
else stu[q].ranks=q+1;
}
printf("%d\n",times);
for(int i=0;i<times;i++)
{
printf("%s %d %d %d\n",stu[i].num,stu[i].ranks,stu[i].k0,stu[i].rankp);
}
}