【PAT甲级】1039 Course List for Student (25分)

解题过程的小记录,如有错误欢迎指出。

难度:三星(用map会超时,必须用vector配合hash散列,hash的大小设置和映射过程可以背一下)

题目分析

给出每一门课的选课学生,然后按照学生名字进行查询,输出每个学生所选的课程
(其实题目中说了名字是有一定规律的:三个大写字母+一个数字,就是在暗示用hash映射来做)

注意点

  1. 最后一个测试点数据量过大,所以用map的方法过不了
  2. 输出的课程序号需要按照从小到大排序

我的解题过程

思路

  1. 因为学生姓名是三个大写字母+一个数字的结构,所以可以开一个大小为26 * 26 * 26 * 10的vector数组用来映射学生(相当于是一个千位、百位、十位都是26进制,个位是十进制的数字=>这样就不会重复),因为学生会选择多门课程,所以hash表的类型选取vector
  2. 设置一个函数,返回把学生姓名映射到数组上的下标
  3. 按课程输入学生所选的课程
  4. 按照要求进行输出

bug

  1. 刚开始还是选用了map来写,本题用map来写真的十分方便,但是最后一个测试点会gg,会扣一分
  2. 后来改了vector配合散列hash,结果数组大小写错了映射方法也是,导致最后一个测试点报错,会扣两分(这还不如超时呢orz)
  3. 最后一切都对了,但是程序运行不了了,相同的代码可以提交全对,但是在VS2017中运行不了,后来查了一下是因为数组开太大了,不能放在main里,一定要放的话可以加static设置,变为全局变量,也可以直接放在外面变成全局变量

代码

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

using namespace std;

vector<int> stu[26 * 26 * 26 * 10];//***编译器毛病:数组下标开大了放在全局变量就可以运行

int indexnum(string s) {
	int result = 0;
	for (int i = 0; i < 3; i++) {
		result = result * 26 + (s[i] - 'A');
	}
	result = result * 10 + (s[3] - '0');
	return result;
}

int main()
{
	int n, k;
	cin >> n >> k;
	
	for (int i = 0; i < k; i++) {
		int courseid, stunum;
		scanf("%d %d", &courseid, &stunum);
		for (int j = 0; j < stunum; j++) {
			string s;
			cin >> s;
			stu[indexnum(s)].push_back(courseid);
		}
	}
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		int sizenum = stu[indexnum(s)].size();
		cout << s << " " << sizenum;
		if (sizenum != 0) {
			sort(stu[indexnum(s)].begin(), stu[indexnum(s)].end());
			for (int j = 0; j < sizenum; j++) {
				printf(" %d", stu[indexnum(s)][j]);
			}
		}
		printf("\n");
	}
    return 0;
}

dalao的代码

全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~

借鉴点

  1. hash的大小设置,和下标映射方法最好了解并背下来
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值