PAT A1039 Course List for Student (25 分)

Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤40,000), the number of students who look for their course lists, and K (≤2,500), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students N​i​​ (≤200) are given in a line. Then in the next line, N​i​​ student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.
Output Specification:
For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student’s name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.
Sample Input:
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

Sample Output:
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

题目大意:

有N个学生,K门课。现在给出选择每门课的学生姓名,并在之后给出N个学生的姓名,要求按顺序给出每个学生的选课情况。

思路:

正常思路:读取每门课的所有选课学生,然后将该课程编号加入所有选择该门课的学生中去,这样就可以在最后输出所有学生的选课情况。但是本题有两个问题;一是学生是通过姓名的方式给出的;二十考生数与课程数的乘积过大,会导致直接开数组会有 “ 内存超限 ”的问题。
对于第一个问题,采用map去实现姓名与学生编号之间的映射,但是由于本题的最后一组数据比较庞大,容易超时。因此本题只能使用字符串hash进行求解。字符串hash在配套用书中已经介绍过。(个人理解,就是将字符串的每一个字母换成相应的数字,然后拼成一个很大的数字,记住不要太长,太长的话会溢出)
下面是本题字符串hash的代码:

int getID(char name[])
{
	int id = 0;
	for(int i = 0; i < 3; i++)
	{
		id = id * 26 + (name[i] - 'A');
	}
	id = id * 10 + (name[3] - '0');
	return id;
}

对于第二个问题,则需要建立vector数组来存放不同学生各自选择的所有课程的编号由于前面的通过字符串hash将学生的姓名转化为数字,因此vector数组的大小至少是26 * 26 * 26 * 10(即三个英文字母加一个数字)

注意点

  1. 使用map,string都会导致超时,因此最好不要使用;
  2. 数据庞大,不要使用cin和cout进行输入和输出;
  3. 二维数组存放数据,容易内存超限,vector比较节省空间。
  4. 自我意见:这道题很好地解释了vector的使用和优点所在之处。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 40010;
const int M = 26 * 26 * 26 * 10 + 1;
int getID(char name[])
{
 int id = 0;
 for(int i = 0; i < 3; i++)
 {
  id = id * 26 + (name[i] - 'A'); 
 }
 id = id * 10 + (name[3] - '0');
 return id;
}
int main()
{
 vector<int> v[M];
 int n, k, x, y, num;
 char name[5];
 scanf("%d%d", &n, &k);
 for(int i = 0; i < k; i++)
 {
  scanf("%d%d", &x, &y);
  for(int j = 0; j < y; j++)
  {
   scanf("%s", name);
   num = getID(name);
   v[num].push_back(x);
  }
 }
 for(int i = 0; i < n; i++)
 {
  scanf("%s", name);
  num = getID(name);
  printf("%s %d", name, v[num].size());
  sort(v[num].begin(), v[num].end());
  for(int j = 0; j < v[num].size(); j++)
  {
   printf(" %d", v[num][j]);
  }
  printf("\n");
 }
 return 0;
}

这里想要强调一个点,就是有关vector的二维数组的构建,有两种形式。
第一种:

vector<vector<int> > name;          //注意空格

第二种:

vector<typename> Arrayname[arraysize];

这两者的区别就在于后者的一维数组是定长的,长度为给定的arraysize,而前者一维和二维数组都是vector数组
不定长,可改变的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值