-
题目描述:
-
有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息。
-
输入:
-
测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。
每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整形数)、成绩(小于等于100的正数)。
-
输出:
-
将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。
然后输出学生信息,按照如下格式:
姓名 年龄 成绩
-
样例输入:
-
3 abc 20 99 bcd 19 97 bed 20 97
-
样例输出:
-
bcd 19 97 bed 20 97 abc 20 99
-
提示:
-
学生姓名的字母序区分字母的大小写,如A要比a的字母序靠前(因为A的ASC码比a的ASC码要小)。
-
来源:
题目分析:
这是清华2000年机试难度相对较大的一题,其他3题都是水题。
本题考察的核心是结构体的排序。
去年暑假的我显得很憨厚,手写了一个compare函数,再手写了一个归并排序函数,很费劲的AC了。
今天用了qsort()排序,大大简化了代码量,提高了效率。
这道题放到今天看来,也就是比水题难度稍大。
关于qsort()及sort()排序和对应的cmp函数,大家可以去百度学习一下。
源代码1(去年的)
#include <iostream>
#include <cstdlib>
#include <cstring>
typedef struct {
char name[102];
int age;
int score;
}student;
bool compare(student a, student b)
{
if(a.score<b.score)
return 1;
else if(a.score==b.score)
{
int la=strlen(a.name), lb=strlen(b.name);
int lmin;
if(la<=lb) lmin = la;
else lmin = lb;
int k=0;
while(k<=lmin)
{
if(a.name[k]<b.name[k])
return 1;
else if(a.name[k]>b.name[k])
return 0;
k++;
}
if(a.age<b.age)
return 1;
}
return 0;
}
void Merge(student array[], int p, int q, int r)
{
int i, j, k;
student* temp = (student*)malloc((r-p+1)*sizeof(student));
for(i=p,j=q+1,k=0; i<=q && j<=r; k++)
{
if(compare(array[i], array[j]))
temp[k]=array[i++];
else
temp[k]=array[j++];
}
while(i<=q)
temp[k++]=array[i++];
while(j<=r)
temp[k++]=array[j++];
for(k=0; k<(r-p+1); k++)
array[p+k] = temp[k];
free(temp);
}
void MergeSort(student array[], int low, int high)
{
int mid = 0;
if(low<high)
{
mid = (low+high)/2;
MergeSort(array, low, mid);
MergeSort(array, mid+1,high);
Merge(array, low, mid, high);
}
}
int main()
{
using namespace std;
int n;
while(cin >> n)
{
student stu[1001];
int i;
for(i=1; i<=n; i++)
cin >> stu[i].name >> stu[i].age >> stu[i].score;
MergeSort(stu, 1, n);
for(i=1; i<=n; i++)
cout << stu[i].name << " " << stu[i].age << " " << stu[i].score << endl;
}
return 0;
}
/**************************************************************
Problem: 1061
User: superlc320
Language: C++
Result: Accepted
Time:710 ms
Memory:1556 kb
****************************************************************/
源代码2(今天改进的)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student //定义学生结构体
{
char name[102];
int age;
int score;
}student;
int cmp(const void *a, const void *b) //qsort()的cmp函数
{
student* sa=(student*)a; //简化后面的代码
student* sb=(student*)b;
if(sa->score == sb->score)
{
if(!strcmp(sa->name, sb->name))
return sa->age - sb->age; //如果分数相同,名字也相同,则比较年龄
else
return strcmp(sa->name, sb->name); //如果分数相同,名字不同,则比较名字
}
return sa->score - sb->score; //如果分数不同则比较分数
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
student stu[1001];
int i;
for(i = 0; i < n; i++)
scanf("%s%d%d", stu[i].name, &stu[i].age, &stu[i].score);
qsort(stu, n, sizeof(student), cmp); //运用qsort()或者sort()可以避免手写排序算法
for(i = 0; i < n; i++)
printf("%s %d %d\n", stu[i].name, stu[i].age, stu[i].score);
}
//system("pause");
return 0;
}
/**************************************************************
Problem: 1061
User: superlc320
Language: C++
Result: Accepted
Time:60 ms
Memory:1064 kb
****************************************************************/