题目在这:题目传送门
题目大概的意思呢,就是有N个学生,K门课,给出选择每门课的学生姓名,并在最后给出N个学生的姓名,要求按顺序给出每个学生的选课情况。依次输出学生的姓名,选课数,课程的代号。
我自己写代码的时候准备拿每个课程对应建立vector,但是在vector存放string的时候卡住了,后来搜到了柳神的代码,仔细拜读了一下,在这篇博客里详细讲解。思路有所不同。
这个题目的核心就是用vector存数据。
思路概览:
- 把学生的名字XXXX(前三个是英文,第四个是数字)转换成一个int,手写一个hash的方法,映射出来每个名字对应的值。
- 每个学生选的课,存在对应(名字映射出来的hash值)下标的vector里面。
- 最后用sort函数排序之后输出。
有了这个思路呢,就好写代码了。
首先根据第一点:
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int getid(char *name){
int id = 0;
for(int i = 0;i<3;i++)//因为前三个是英语,所以for只要做三次
id = 26 * id + name[i] - 'A';//这个就是把每个英语字母取出来(类似于转换为26进制存起来)
id = id * 10 + name[3] - '0';//这个是把id后面加个0,用后面的数字填上去。
return id;
}
const int maxn = 26 * 26 * 26 * 10 + 10;
vector<int> v[maxn];
这一部分写出了思路的第一个,封装成了getid。
int main(){
int n,m,no,num,id=0;
char name[5];
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d %d",&no,&num);
for(int j=0;j<num;j++){
scanf("%s",name);//存名字
id = getid(name);//转换成int
v[id].push_back(no);//课程序号存入对应的int下标中的vector的后面
}
}
这一部分写出了思路的第二个,存起来了每个学生对应的课程号。
//接上面的代码
for(int i = 0;i<n;i++){
scanf("%s",name);//读取学生名字
id = getid(name);//转换成int
sort(v[id].begin(),v[id].end());//找到这个int对应的vector排序
printf("%s %d",name,v[id].size());//打印这个名字,和这个学生选课数目
for(int i = 0; i<v[id].size();i++)
printf(" %d",v[id][i]);//打印每一个课的序号
printf("\n");
}
}
这一部分代码处理输入数据的最后一行,读取,排序,输出。
完整代码:
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int getid(char *name){
int id = 0;
for(int i = 0;i<3;i++)
id = 26 * id + name[i] - 'A';
id = id * 10 + name[3] - '0';
return id;
}
const int maxn = 26 * 26 * 26 * 10 + 10;
vector<int> v[maxn];
int main(){
int n,m,no,num,id=0;
char name[5];
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d %d",&no,&num);
for(int j=0;j<num;j++){
scanf("%s",name);
id = getid(name);
v[id].push_back(no);
}
}
for(int i = 0;i<n;i++){
scanf("%s",name);
id = getid(name);
sort(v[id].begin(),v[id].end());
printf("%s %d",name,v[id].size());
for(int i = 0; i<v[id].size();i++)
printf(" %d",v[id][i]);
printf("\n");
}
}