2017年北京理工大学研究生复试机试题:学生信息系统

Problem Description

建立一个学生信息系统,输入学生信息,输出有挂科同学的信息,再按照平均成绩从高到低排序输出。

Input

首先输入学生的个数N,在接下来的N行,每行输入由学生姓名(小写拼音),第一科成绩、第二科成绩、第三科成绩以及总分构成。

Output

首先输出学科中有挂科的同学信息,并将其姓名和单科成绩以如下格式输出:
*[qianer] 65 32 77
然后按照平均成绩由高到低,输出所有同学姓名和单科成绩。

Sample Input

5
zhaoyi 70 80 90 240
qianer 65 32 77 174
sunsan 100 55 68 223
lisi 86 77 90 253
wangwu 100 59 66 225

Sample Output

*[qianer] 65 32 77
*[sunsan] 100 55 68
*[wangwu] 100 59 66
lisi 86 77 90 253
zhaoyi 70 80 90 240
wangwu 100 59 66 225
sunsan 100 55 68 223
qianer 65 32 77 174

解题思路

  1. 定义学生类型结构体,其中包含姓名,第一、二、三科成绩,总分以及是否挂科。
  2. 声明students数组,录入学生数据,并通过第一、二、三科成绩判断该生是否挂科。
  3. 输出挂科学生信息,即结构体数组元素成员变量中isFailed值为true的元素。
  4. 默写快排代码模板,改为以总分划分数组,对students数组按照总分降序排序(算法笔记p142快速排序)。
  5. 打印排序后的学生信息。

经验总结

  1. 生成随机数需加头文件stdlib.h、time.h和math.h。
  2. srand((unsigned) time(NULL))用于初始化随机种子(记住就行)。
  3. rand()函数生成[0,RAND_MAX]范围内的随机数,然后用这个随机数除以RAND_MAX得到一个[0,1]范围内的浮点数;用这个浮点数乘以(right - left),加上left,再用round()函数四舍五入后,得到[left,right]范围内的随机数;这个浮点数相当于[left,right]范围内的比例位置。
  4. 例:rand()生成的随机数经过处理得到浮点数为0.5,left = 2,right = 5,right - left = 3,3 * 0.5 = 1.5,1.5 + 2 = 3.5,round(3.5) = 4,得到[2,5]范围内的随机数4。

代码实现(C)

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define MaxSize 1000

typedef struct Student {
    char name[20];
    int score[3];
    int sum;
    bool isFailed;   // 用于记录该生是否挂科
} Student;

Student students[MaxSize];

// 输入数据并记录是否挂科
void input(int N, int *score) {
    for (int i = 0; i < N; ++i) {
        // 输入姓名
        scanf("%s", students[i].name);
        // 输入各科成绩
        for (int j = 0; j < 3; ++j) {
            scanf("%d", score);
            students[i].score[j] = *score;
        }
        // 输入总分
        scanf("%d", &students[i].sum);
        // 判断是否挂科
        for (int j = 0; j < 3; ++j) {
            if (students[i].score[j] < 60) {
                students[i].isFailed = true;
                break;
            }
            students[i].isFailed = false;
        }
    }
}

// 打印挂科学生信息
void printFailed(int N) {
    for (int i = 0; i < N; ++i)
        if (students[i].isFailed)
            printf("*[%s] %d %d %d\n", students[i].name, students[i].score[0], students[i].score[1],
                   students[i].score[2]);
}

// 交换学生信息
void swap(int left, int pivotIndex) {
    Student pivot = students[pivotIndex];
    students[pivotIndex] = students[left];
    students[left] = pivot;
}

// 选取随机枢轴,对区间[left, right]进行划分
int randPartition(int left, int right) {
    // 初始化随机种子
    srand((unsigned) time(NULL));
    // 生成[left, right]内的随机数pivotIndex作为枢轴
    int pivotIndex = (int) round(1.0 * rand() / RAND_MAX * (right - left) + left);
    // 交换students[left]与枢轴元素
    swap(left, pivotIndex);
    // 以随机枢轴划分数组
    Student temp = students[left];
    while (left < right) {
        while (left < right && students[right].sum <= temp.sum) right--;
        students[left] = students[right];
        while (left < right && students[left].sum > temp.sum) left++;
        students[right] = students[left];
    }
    students[left] = temp;
    return left;
}

// 快速排序
void quick_sort(int left, int right) {
    if (left < right) {
        int pos = randPartition(left, right);
        quick_sort(left, pos - 1);
        quick_sort(pos + 1, right);
    }
}

// 打印学生信息
void printInfo(int N) {
    for (int i = 0; i < N; ++i)
        printf("%s %d %d %d\n", students[i].name, students[i].score[0], students[i].score[1], students[i].score[2]);
}

int main() {
    int N, score;
    while (~scanf("%d", &N)) {
        // 录入学生数据并记录挂科学生信息
        input(N, &score);
        // 打印挂科学生信息
        printFailed(N);
        // 对学生按照总分降序排序
        quick_sort(0, N - 1);
        // 打印学生信息
        printInfo(N);
    }
    return 0;
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值