一:题目
假设全校有最多40000名学生和最多2500门课程。现给出每个学生的选课清单,要求输出每门课的选课学生名单。
输入格式:
输入的第一行是两个正整数:N(≤40000),为全校学生总数;K(≤2500),为总课程数。此后N行,每行包括一个学生姓名(3个大写英文字母+1位数字)、一个正整数C(≤20)代表该生所选的课程门数、随后是C个课程编号。简单起见,课程从1到K编号。
输出格式:
顺序输出课程1到K的选课学生名单。格式为:对每一门课,首先在一行中输出课程编号和选课学生总数(之间用空格分隔),之后在第二行按字典序输出学生名单,每个学生名字占一行。
输入样例:
10 5
ZOE1 2 4 5
ANN0 3 5 2 1
BOB5 5 3 4 2 1 5
JOE4 1 2
JAY9 4 1 2 5 4
FRA8 3 4 2 5
DON2 2 4 5
AMY7 1 5
KAT3 3 5 4 2
LOR6 4 2 4 1 5
输出样例:
1 4
ANN0
BOB5
JAY9
LOR6
2 7
ANN0
BOB5
FRA8
JAY9
JOE4
KAT3
LOR6
3 1
BOB5
4 7
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
5 9
AMY7
ANN0
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
二:思路
思路:1.用map容器<int,string>;每门课对应一群学生
2.然后截取字符串,题目给出的是名字是的格式是固定的
3.然后用vector容器 用其sort方法排序的功能(字典序也就是 sort()排序 )
三:上码
方法一:
/**思路:1.用map容器<int,string>;每门课对应一群学生2.然后截取字符串,题目给出的是名字是的格式是固定的3.然后用vector容器 用其sort方法排序的功能(字典序也就是 sort()排序 )
*/
#include<bits/stdc++.h>
using namespace std;
map<int,string>m1;
map<int,string>::iterator mt;int main(){int N,K;int count = 1;cin >> N >> K;for( int i = 0; i < N; i++ ){char ch[6];scanf("%s",ch);int n;cin >> n;for( int j = 0; j < n; j++){int course;cin >> course;m1[course] += ch;} }for( mt = m1.begin(); mt != m1.end(); mt++){vector<string>v;string str = mt->second;if( mt->first != count){cout << count << ' ' << "0" << endl; }count++;printf("%d %d\n",mt->first,str.size() / 4);for( int i = 0; i < str.size(); i = i + 4 ){v.push_back(str.substr(i,4));}sort(v.begin(),v.end());for( int i = 0; i < v.size(); i++ ){printf("%s\n",(v[i]).c_str());}}} //10 5
//ZOE1 2 4 5
//ANN0 3 5 2 1
//BOB5 4 4 2 1 5
//JOE4 1 2
//JAY9 4 1 2 5 4
//FRA8 3 4 2 5
//DON2 2 4 5
//AMY7 1 5
//KAT3 3 5 4 2
//LOR6 4 2 4 1 5
方法二:
/**思路:用vector的一对多 即一个课程编号对应好几个名字 */
#include<bits/stdc++.h>
using namespace std;int main(){int N,K;vector <string> v[2600];scanf("%d%d",&N,&K);for(int i = 0; i < N; i++){int nums;char name[6];scanf("%s%d",name,&nums);for(int j = 0; j < nums; j++){int course;scanf("%d",&course);v[course].push_back(name);} } for(int i = 1; i <= K; i++){printf("%d %d\n",i,v[i].size());sort(v[i].begin(),v[i].end());// for(string name:v[i]){
// printf("%s\n",name.c_str());
// }for(int j = 0; j < v[i].size(); j++){printf("%s\n",v[i][j].c_str());}}}
四:超时解决:
本题当中,需要把输出输出改为scanf 和printf 否则最后一个点会出现超时问题
五:知识速递(vector和map的基本用法 不了解的兄弟们可以学一下哈)
map的基本用法
vector的基本用法
六:记录失败码
这个码在处理学生的具体名字时,我用的是set容器,但是最后一个测试点过不去,用cin cout 就运行超时,换成sancf 和printf就答案错误 脑壳疼。我就换成vector ,然后就和过去了。
/**思路:1.用map容器<int,string>;每门课对应一群学生2.然后截取字符串,题目给出的是名字是的格式是固定的3.然后用set容器 用其自动排序的功能(字典序也就是 sort()排序 )
*/
#include<bits/stdc++.h>
using namespace std;int main(){int N,K;int count = 1;map<int,string>m1;map<int,string>::iterator mt;cin >> N >> K;for( int i = 0; i < N; i++ ){string name;cin >> name;int n;cin >> n;for( int j = 0; j < n; j++){int course;cin >> course;m1[course] += name;} }for( mt = m1.begin(); mt != m1.end(); mt++){set<string>s1;set<string>::iterator st;string str = mt->second;if( mt->first != count){cout << count << ' ' << "0" << endl; }count++;cout << mt->first << ' ' << str.size() / 4 << endl;for( int i = 0; i < str.size(); i = i + 4 ){s1.insert(str.substr(i,4)); }for( st = s1.begin(); st != s1.end(); st++ ){cout << *st << endl;}}} //10 5
//ZOE1 2 4 5
//ANN0 3 5 2 1
//BOB5 4 4 2 1 5
//JOE4 1 2
//JAY9 4 1 2 5 4
//FRA8 3 4 2 5
//DON2 2 4 5
//AMY7 1 5
//KAT3 3 5 4 2
//LOR6 4 2 4 1 5