首页 > 试题广场 >

小猿的冠军班级

[编程题]小猿的冠军班级
  • 热度指数:124 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解

猿辅导课程中需要记录各个班的同学们的出勤情况并进行班级排名,授予冠军班级的奖励。

但是今天粗心的小猿出公司门的时候摔了一跤,把榜单给弄丢了,幸好考勤记录还没丢,但是顺序被弄乱了,现在他把考勤记录和班级名册整理了一下,请你写个程序,帮他把班级排名恢复吧!

排名规则是各班的出勤率,即老师在教室时同学们在教室听讲的比例,具体为:班级同学有效出勤分钟数之和/(老师在教室时间*班级人数),出勤率相同的班级,按班级名称的字典序进行排序。
其中,有效出勤分钟数表示该同学与老师同在教室内的时间和,即各个区间的结束时间(分)与开始时间(分)之差的和。

输入描述:
第一行为两个数字N,M,以空格分隔,分别表示总考勤记录数和班级个数。

接下来M行,每行表示一个班级的情况,其中第i+1行数据为:

数字Ki表示该班级人数,数字ti表示该班老师的用户id,namei表示班级的名称,接下来Ki个数字表示该班的同学的用户id。

例如:3 999 yuanxiaoyiban 0001 0002 0004

表示yuanxiaoyiban班的老师id为999,3位同学的用户id分别为0001,0002,0004

接下来N行表示乱序的考勤记录,每一行表示一条记录,记录由命令cmdj表示进出教室情况,有IN和OUT两种,数字idj表示进出教室的用户id,timej表示该记录发生的时间距2000年1月1日的分钟数。

例如:IN 999 1表示id为999的用户在2000年1月1日00:01进入了教室。

数据保证,
所有人开始和结束记录时都不在教室内;
每个班级的老师在教室时间和班级人数不为0;同一个用户在同一分钟可以进出教室各一次;班级名称各不相同。


输出描述:
共M行,第i行为排名为i的班级的名称。
示例1

输入

12 2
3 999 yuanxiaoyiban 0001 0002 0004
2 9988 yuanxiaoerban 0003 0009
IN 0001 9001
OUT 0001 9006
IN 999 8888
OUT 999 8888
IN 999 9003
OUT 999 9004
IN 9988 9005
OUT 9988 9006
IN 0003 9001
OUT 0003 9002
IN 0003 9005
OUT 0003 9006

输出

yuanxiaoerban
yuanxiaoyiban

说明

yuanxiaoyiban出勤率为1/3,yuanxiaoerban出勤率为1/2,因此yuanxiaoerban比yuanxiaoyiban出勤率高

备注:
数据范围:
0<N<300000,
0<M<10000,
所有班级的人数Ki总计小于20000,
所有班级名称namei的总长度小于1000000,
且都由小写字母a-z组成。
0<id<2x109,
记录时间0<timej <1x105
提示:由于笔试时间较为紧张,本题调试难度较大,建议动手前仔细阅读样例。
最讨厌这种题了,本身很简单,但是对输入的数据没有说明,直接告诉我每个人的出入时间有多段,并且出入顺序不一定有序,不就几下的事情吗
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    static int N;
    static int M;
    static class Room{
        String cId;
        double score;
        Person t;
        HashMap<String,Person> s = new HashMap<>();
        public Room(Person teacher, String id){
            this.t = teacher;
            this.cId = id;
        }
    }
    static class Person{
        String pId;
        ArrayList<Integer> in = new ArrayList<>();
        ArrayList<Integer> out = new ArrayList<>();
        public Person(String id){
            this.pId = id;
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        N = scanner.nextInt();
        M = scanner.nextInt();
        HashMap<String,Room> roomMap = new HashMap<>();
        HashMap<String,Person> personMap = new HashMap<>();
        for (int i = 0; i < M; i++) {
            int num = scanner.nextInt();
            String tId = scanner.next();
            String id = scanner.next();
            Person t = new Person(tId);
            personMap.put(tId,t);
            Room r = new Room(t,id);
            for (int j = 0; j < num; j++) {
                String name = scanner.next();
                Person st = new Person(name);
                r.s.put(name,st);
                personMap.put(name,st);
            }
            roomMap.put(id, r);
        }
        for (int i = 0; i < N; i++) {
            if (scanner.next().equals("IN"))
                personMap.get(scanner.next()).in.add(scanner.nextInt());
            else
                personMap.get(scanner.next()).out.add(scanner.nextInt());

        }
        roomMap.forEach((id, room) -> {
            room.t.in = room.t.in.stream().sorted(Comparator.comparingInt(Integer::intValue)).collect(Collectors.toCollection(ArrayList::new));
            room.t.out = room.t.out.stream().sorted(Comparator.comparingInt(Integer::intValue)).collect(Collectors.toCollection(ArrayList::new));
            room.s.forEach((sId,p)->{
                p.in = p.in.stream().sorted(Comparator.comparingInt(Integer::intValue)).collect(Collectors.toCollection(ArrayList::new));
                p.out = p.out.stream().sorted(Comparator.comparingInt(Integer::intValue)).collect(Collectors.toCollection(ArrayList::new));
                for (int i = 0; i < p.in.size(); i++) {
                    for (int j = 0; j < room.t.in.size(); j++) {
                        int temp = Math.min(p.out.get(i),room.t.out.get(j)) - Math.max(p.in.get(i),room.t.in.get(j));
                        if (temp>0)
                            room.score += temp;
                    }
                }
            });
            long buttom = 0;
            for (int i = 0; i < room.t.in.size(); i++) {
                buttom += (room.t.out.get(i) - room.t.in.get(i));
            }
            room.score /= buttom * room.s.size();
        });
        roomMap.values().stream().sorted(Comparator.comparing(r->r.cId)).sorted(Comparator.comparingDouble(r->-r.score)).map(room -> room.cId).forEach(System.out::println);
    }
}


编辑于 2020-11-02 20:11:45 回复(0)
import sys

nm = sys.stdin.readline()
n, m = [int(i) for i in nm.split()]

class_table = []
all_records = []
for i in range(m):
    class_table.append(sys.stdin.readline().split())
for i in range(n):
    all_records.append(sys.stdin.readline().split())
all_records = sorted(all_records, key=lambda x: x[1])

numbers_of_students = []
teachers_IDs = []
name_of_class = []
students_IDs = []

for each_class in range(m):
    numbers_of_students.append(class_table[each_class][0])
    teachers_IDs.append(class_table[each_class][1])
    name_of_class.append(class_table[each_class][2])
    students_IDs.append(class_table[each_class][3:])

teacher_time = [[] for i in range(m)]
student_time = [[] for i in range(m)]

for i in range(0, len(all_records), 2):
    if all_records[i][1] in teachers_IDs:
        index = teachers_IDs.index(all_records[i][1])
        teacher_time[index].append(list(range(int(all_records[i][2]), int(all_records[i+1][2])+1)))
        # teacher_time[index].append(range(int(all_records[i][2]), int(all_records[i+1][2])))
    else:
        for index in range(m):
            if all_records[i][1] in students_IDs[index]:
                student_time[index].append(list(range(int(all_records[i][2]), int(all_records[i+1][2])+1)))

rates = []
for i in range(m):
    time1 = [i for j in teacher_time[i] if len(j) > 1 for i in j]
    time2 = [i for j in student_time[i] if len(j) > 1 for i in j]
    t = [i for i in time2 if i in time1]
    rates.append(len(t)/(len(time1)*int(numbers_of_students[i])))

index = [i[0] for i in sorted(enumerate(rates), key=lambda x:x[1], reverse=True)]

for i in index:
    print(name_of_class[i])
抛砖引玉吧,内存超限了,等大佬优化。
感觉可以直接用几个range求交集。
发表于 2020-07-29 16:54:48 回复(0)