PAT-ADVANCED1039——Course List for Student

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805447855292416

题目描述:

题目翻译:

1039 学生课程表

浙江大学有4万名学生,开设2500门课程。 现在给出所有课程的学生名单,你需要为每个来查询的学生输出注册的课程列表。

输入格式:

每个输入文件包含一个测试用例。对于每个测试用例,第一行包含2个正整数:N(<= 40,000),查找课程列表的学生人数,以及K(<= 2,500),课程总数。然后按以下格式给出课程(编号从1到K)的学生姓名列表:对于每个课程i,首先在一行中给出课程索引i和注册学生数N(≤200)。 然后在下一行,给出N个选择该课程的学生姓名。 学生姓名由3个大写英文字母和一位数字组成。 最后一行包含来查询的学生的N个名字。 一行中的所有名称和数字都用空格分隔。

输出格式:

对于每个测试用例,以N行打印结果。 每行对应一名学生,格式如下:首先打印学生的姓名,然后打印该学生的注册课程总数,最后按顺序递增课程索引。 必须以与输入相同的顺序打印查询结果。 一行中的所有数据必须用空格分隔,行末没有额外的空格。

输入样例:

11 5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6 NON9

输出样例:

ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0

知识点:手动哈希映射

思路:用字符数组来存储字符串,手动哈希映射学生姓名和数字

对于姓名中的大写字母部分,我们将其视作是一个26进制数,将其转换为10进制,再在末尾添上数字部分即得到了该姓名的哈希映射数字。

而对于字符串的读取,用string会超时。

时间复杂度和每个学生的选课情况有关。空间复杂度是O(26 * 26 * 26 * 10 + 1)。

C++代码:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int change(char* name);

int main(){
	int N, K, courseId, courseCapacity;
	scanf("%d %d", &N, &K);
	char name[5];
	vector<int> students[175761];
	for(int i = 0; i < K; i++){
		scanf("%d %d", &courseId, &courseCapacity);
		for(int j = 0; j < courseCapacity; j++){
			scanf("%s", name);
			int id = change(name);
			students[id].push_back(courseId);
		}
	}
	for(int i = 0; i < N; i++){
		scanf("%s", name);
		int id = change(name);
		printf("%s ", name);
		printf("%d", students[id].size());
		sort(students[id].begin(), students[id].end());
		for(int j = 0; j < students[id].size(); j++){
			printf(" %d", students[id][j]);
		}
		printf("\n");
	}
	return 0;
}

int change(char* name){
	int result = 0;
	for(int i = 0; i < 3; i++){
		result = result * 26 + *(name + i) - 'A';
	}
	result = result * 10 + *(name + 3) - '0';
	return result;
}

C++解题报告:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值