(C卷,100分)- 智能成绩表(Java & JS & Python & C)

题目描述

小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?

输入描述

第 1 行输入两个整数,学生人数 n 和科目数量 m。

  • 0 < n < 100
  • 0 < m < 10

第 2 行输入 m 个科目名称,彼此之间用空格隔开。

  • 科目名称只由英文字母构成,单个长度不超过10个字符。
  • 科目的出现顺序和后续输入的学生成绩一一对应。
  • 不会出现重复的科目名称。

第 3 行开始的 n 行,每行包含一个学生的姓名和该生 m 个科目的成绩(空格隔开)

  • 学生不会重名。
  • 学生姓名只由英文字母构成,长度不超过10个字符。
  • 成绩是0~100的整数,依次对应第2行种输入的科目。

第n+2行,输入用作排名的科目名称。若科目不存在,则按总分进行排序。

输出描述

输出一行,按成绩排序后的学生名字,空格隔开。成绩相同的按照学生姓名字典顺序排序。

用例

输入 3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 100 82
shuxue
输出 xiaohua fangfang minmin
说明 按shuxue成绩排名,依次是xiaohua、fangfang、minmin
输入 3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 90 95
zongfen
输出 fangfang minmin xiaohua
说明 排序科目不存在,按总分排序,fangfang和minmin总分相同,按姓名的字典顺序,fangfang排在前面

 

题目解析

本题是一道排序题。难度在于排序规则是动态的,不是固定的。

本题要求按照最后一行输入的科目的分数进行排序,如果对应科目不存在,则按照总分进行排序。

我的解题思路是:

首先,定义一个排名要素数组rank,分别记录各科成绩以及总分,即该排名要素数组rank的长度为 m + 1。

  • 第rank[0]~rank[m-1]上,记录的是第二行输入科目顺序对应科目分数。
  • 第rank[m]上,记录的是所有科目的总分。

然后,定义一个有效要素索引(即最终用于指定规则的排序要素的索引),比如:

  • 最后一行输入了shuxue,那么我就去第二行输入:yuwen shuxue,中去找对应出现序号为 1,那么有效要素的索引就是1,最终用于制定排序规则的值就是 rank[1]。
  • 如果最后一行输入的科目,在第二行中不存在,那么就是按照总分制定排序规则,此时排序要素取 rank[m]。

如果排序要素值相同(可能是某科成绩,可能是总分),那么就再按照学生姓名的字典序排序。

更多实现细节请看代码,已添加详细注释。

JavaScript算法源码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  class Student {
    constructor(name, rank) {
      this.name = name; // 学生姓名
      this.rank = rank; // 排名要素
    }
  }

  // 学生人数, 科目数量
  const [n, m] = (await readline()).split(" ").map(Number);

  // key是科目名称,val是科目出现顺序的序号
  const subject_rankIdx = {};

  // 输入的m个科目
  const subjects = (await readline()).split(" ");

  for (let i = 0; i < m; i++) {
    subject_rankIdx[subjects[i]] = i;
  }

  const students = [];
  for (let i = 0; i < n; i++) {
    const tmp = (await readline()).split(" ");

    // 学生姓名
    const name = tmp[0];

    // 学生给定科目的分数(m个)
    const scores = tmp.slice(1).map(Number);
    // 学生所有科目的总分
    const score_sum = scores.reduce((a, b) => a + b);

    // 排名要素,0~m-1索引上的是给定科目成绩,m索引上的是总分
    const rank = [...scores, score_sum];

    students.push(new Student(name, rank));
  }

  // 用作排名的科目名称
  const subject = await readline();

  // 用作排名的科目名称的排名要素序号
  let rankIdx = subject_rankIdx[subject];
  // 如果用作排名的科目名称不存在,则按总分排名,对应序号是m
  if (rankIdx == undefined) {
    rankIdx = m;
  }

  // 按照排名要素排名,如果排名要素值相同,则按照学生姓名字典序排序
  students.sort((a, b) =>
    a.rank[rankIdx] != b.rank[rankIdx]
      ? b.rank[rankIdx] - a.rank[rankIdx]
      : strcmp(a.name, b.name)
  );

  console.log(students.map((a) => a.name).join(" "));
})();

function strcmp(a, b) {
  if (a == b) {
    return 0;
  } else if (a > b) {
    return 1;
  } else {
    return -1;
  }
}

Java算法源码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.StringJoiner;

public class Main {
  static class Student {
    String name; // 学生姓名
    int[] rank; // 排名要素

    public Student(String name, int[] rank) {
      this.name = name;
      this.rank = rank;
    }
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    // 学生人数
    int n = sc.nextInt();

    // 科目数量
    int m = sc.nextInt();

    // key是科目名称,val是科目出现顺序的序号
    HashMap<String, Integer> subject_rankIdx = new HashMap<>();
    for (int i = 0; i < m; i++) {
      subject_rankIdx.put(sc.next(), i);
    }

    ArrayList<Student> students = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      // 学生姓名
      String name = sc.next();

      // rank记录学生排名的要素(0~m-1索引上记录的是各科成绩,m索引上记录的是总分)
      int[] rank = new int[m + 1];
      // 学生的总分
      int score_sum = 0;

      // m 个科目成绩
      for (int j = 0; j < m; j++) {
        rank[j] = sc.nextInt();
        score_sum += rank[j];
      }

      rank[m] = score_sum;

      students.add(new Student(name, rank));
    }

    // 输入用作排名的科目名称
    // 根据用作排名的科目名称获取对应排名要素序号,如果不存在,则按总分排序,排名要素序号取m
    int rankIdx = subject_rankIdx.getOrDefault(sc.next(), m);

    students.sort(
        (a, b) ->
            a.rank[rankIdx] != b.rank[rankIdx]
                ? b.rank[rankIdx] - a.rank[rankIdx]
                : a.name.compareTo(b.name));

    StringJoiner sj = new StringJoiner(" ");
    for (Student student : students) {
      sj.add(student.name);
    }

    System.out.println(sj);
  }
}

Python算法源码

class Student:
    def __init__(self, name, rank):
        self.name = name
        self.rank = rank


# 学生人数, 科目数量
n, m = map(int, input().split())

# key是科目名称,val是科目出现顺序的序号
subject_rankIdx = {}

# 输入的m个科目
subjects = input().split()

for i in range(m):
    subject_rankIdx[subjects[i]] = i

students = []
for i in range(n):
    tmp = input().split()

    # 学生姓名
    name = tmp[0]
    # 学生给定科目的分数(m个)
    scores = list(map(int, tmp[1:]))

    # 排名要素,0~m-1索引上的是给定科目成绩,m索引上的是总分
    rank = []
    rank.extend(scores)
    rank.append(sum(scores))

    students.append(Student(name, rank))

# 用作排名的科目名称
subject = input()

#  用作排名的科目名称的排名要素序号, 如果用作排名的科目名称不存在,则按总分排名,对应序号是m
rankIdx = subject_rankIdx.get(subject, m)

# 按照排名要素排名,如果排名要素值相同,则按照学生姓名字典序排序
students.sort(key=lambda x: (-x.rank[rankIdx], x.name))

print(" ".join(map(lambda x: x.name, students)))

C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_N 100
#define MAX_M 10
#define MAX_SUBJECT_LEN 11
#define MAX_STU_NAME_LEN 11

typedef struct {
    char name[MAX_STU_NAME_LEN]; // 学生姓名
    int *rank; // 排名要素
} Student;

Student *new_Student(char *name, int *rank) {
    Student *student = (Student *) malloc(sizeof(Student));
    strcpy(student->name, name);
    student->rank = rank;
    return student;
}

int rankIdx;

int cmp(const void* a, const void* b) {
    Student* A = *((Student**) a);
    Student* B = *((Student**) b);

    if(A->rank[rankIdx] != B->rank[rankIdx]) {
        return B->rank[rankIdx] - A->rank[rankIdx];
    } else {
        return strcmp(A->name, B->name);
    }
}

int main() {
    // 学生人数, 科目数量
    int n, m;
    scanf("%d %d", &n, &m);

    // 记录科目出现顺序
    char subjects[MAX_M][MAX_SUBJECT_LEN];
    for (int i = 0; i < m; i++) {
        scanf("%s", subjects[i]);
    }

    Student *students[MAX_N] = {NULL};
    int students_size = 0;

    for (int i = 0; i < n; i++) {
        // 学生姓名
        char name[MAX_STU_NAME_LEN];
        scanf("%s", name);

        // rank记录学生排名的要素(0~m-1索引上记录的是各科成绩,m索引上记录的是总分)
        int *rank = (int *) calloc(m + 1, sizeof(int));

        // 学生的总分
        int score_sum = 0;
        // m 个科目成绩
        for (int j = 0; j < m; j++) {
            scanf("%d", &rank[j]);
            score_sum += rank[j];
        }

        rank[m] = score_sum;

        students[students_size++] = new_Student(name, rank);
    }

    char subject[MAX_STU_NAME_LEN];
    scanf("%s", subject);

    // 输入用作排名的科目名称
    // 根据用作排名的科目名称获取对应排名要素序号,如果不存在,则按总分排序,排名要素序号取m
    rankIdx = m;
    for (int i = 0; i < m; i++) {
        if (strcmp(subject, subjects[i]) == 0) {
            rankIdx = i;
            break;
        }
    }

    qsort(students, students_size, sizeof(Student*), cmp);

    printf("%s", students[0]->name);
    for(int i=1; i<students_size; i++) {
        printf(" %s",students[i]->name);
    }

    return 0;
}

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?