/*
题意:
输入:
1、第一行给出总的学生人数,然后是课程数
2、然后给出每一行学生的姓名以及他的选课号
输出:
1、输入课程号,参加课程的学生人数
以及学生姓名,单独一行
解题:
1、以二位诶数组char[N][5]存放输入的姓名,其中char[i]表示第i个姓名
2、在读入数据时,如果某学生(编号i)选择了课程j,那么将该学生编号存到course[j]中,(即course[j].push_back(i)
3、对每一门课,将course[i]中的学生按姓名字典序从小到大排序,然后输出所要结果
learn && wrong:
1、使用string,最后一组数据容易超时,在这种数据量大的时候,最后使用char数组
2、vector来存放每门课程的选课学生的编号,可以有效防止所有学生选了所有课程的极端情况导致得空间超限
3、技巧:如果对字符串排序,那么会导致大量字符串移动,耗时,不如用字符串喜爱宝来代替字符串本身进行排序,耗时少得多
4、思路非常重要:
(向量数组为:每门课程参与的学生i)
首先读入学生人数以及课程数
然后读入学生以及他的选课数(用name[i]存学生)
接下来遍历选课数,读入选课号,将i压入每一个选课向量(其实就是用i作中间变量,来连接名字和选课)
接下来遍历选课,并且用sort排序每一个选课中的,再套一个遍历,遍历选课中的名字
*/
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 40010; //最大学生人数
const int maxc = 2510; //最大课程门数
char name[maxn][5]; //maxn个学生
vector<int> course[maxc]; //course[i]存放所有学生编号
bool cmp(int a, int b) {
return strcmp(name[a], name[b]) < 0; //按姓名字典序从小到大排序
}
int main()
{
int n, k, c, courseID;
cin>>n>>k; //学生人数以及课程数
for (int i = 0;i < n;++i) {
cin >> name[i] >> c; //学生姓名以及选课数
for (int j = 0;j < c;j++) { //!!!又是错下标
cin>>courseID; //选择的课程编号
course[courseID].push_back(i); //将学生i加入第courseID门课中!!!核心
}
}
for (int i = 1;i <= k;++i) {
printf("%d %d\n", i, course[i].size()); //第i门课的学生数
sort(course[i].begin(), course[i].end(), cmp); //对第i门课的学生排序
for (int j = 0;j < course[i].size();j++) {
printf("%s\n", name[course[i][j]]); //输出学生姓名
}
}
return 0;
}