题目大意:给出N名学生的选课信息,输出所有课程的选课人数,并按姓名首字母顺序输出名单。
先存储再按姓名排序即可,耗时比较大,有优化空间。
AC代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
int N, K;
scanf("%d%d", &N, &K);
vector<vector<string>> list(N+1);
for (int i = 0; i < N; ++i)
{
char name[10];
int courseNum;
scanf("%s%d", name, &courseNum);
for (int j = 0; j < courseNum; ++j)
{
int courseId;
scanf("%d", &courseId);
list[courseId].push_back(string(name));
}
}
for (int i = 1; i <= K; ++i)
{
printf("%d %d\n", i, list[i].size());
sort(list[i].begin(), list[i].end());
for (int j = 0; j < list[i].size(); ++j)
{
printf("%s\n", list[i][j].c_str());
}
}
return 0;
}
优化方向:
① 建立姓名字符串到整型的映射,仍然采用最简单的方法,即将ABC0看成四位36进制数。
② 建立整型到姓名字符串的映射,避免使用map查找,即依次取出36进制数的每一位即可。
#include <bits/stdc++.h>
using namespace std;
int getId(char* name)
{
return (name[0] - 'A') * pow(36,3) + (name[1] - 'A') * pow(36,2) + (name[2] - 'A') * 36 + name[3] - '0';
}
void getName(int id, char* name)
{
name[0] = id / (int)pow(36,3) + 'A';
name[1] = id % (int)pow(36,3) / (int)pow(36,2) + 'A';
name[2] = id % (int)pow(36,2) / 36 + 'A';
name[3] = id % 36 + '0';
}
int main()
{
int N, K;
scanf("%d%d", &N, &K);
vector<vector<int>> v(K+1);
for (int i = 0; i < N; ++i)
{
char name[5];
int C;
scanf("%s%d", name, &C);
int id = getId(name);
for (int j = 0; j < C; ++j)
{
int courseId;
scanf("%d", &courseId);
v[courseId].push_back(id);
}
}
for (int i = 1; i <= K; ++i)
{
printf("%d %zu\n", i, v[i].size());
sort(v[i].begin(), v[i].end());
for (int j = 0; j < v[i].size(); ++j)
{
char name[5] = {0};
getName(v[i][j], name);
printf("%s\n", name);
}
}
return 0;
}