与之前的一题类似,最后一点超时,是O(m*nlogn)。参考网上代码,不要每次都遍历,只遍历一遍就好。对于每一门课,都将其选课学生标记下来,再遍历一遍学生,若有标记的,则输出。
代码:
//1047 19:20-19:38
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
map<int, vector<string> >m;
bool cmp(const string &a, const string &b)
{
return a<b;
}
int main()
{
int n,k,c,courseId,i,j;
// freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
//cin>>n>>k;
char str[8];
scanf("%d%d",&n,&k);
for(i=0;i<n;i++){
// cin>>sname>>c;
getchar();
scanf("%s%d",str,&c);
string sname(str);
for(j=0;j<c;j++){
//cin>>courseId;
scanf("%d",&courseId);
m[courseId].push_back(sname);
}
}
for(i=1;i<=k;i++){
sort(m[i].begin(),m[i].end(),cmp);
cout<<i<<" "<<m[i].size()<<endl;
for(j=0;j<m[i].size();j++){
cout<<m[i][j]<<endl;
}
}
return 0;
}
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int N, K;
struct people{
char name[5];
int id;
}str[40001];
int cnt[2501];
vector<int> buf[2501];
char bucket[40001];
bool mycmp(const struct people &a, const struct people &b) {
return strcmp(b.name, a.name)>0;
}
int main(int argc, char * argv[]) {
scanf("%d %d", &N, &K);
int tmp;
int k;
for (int i=1; i<=N; ++i) {
str[i].id = i;//记录原本的序号
scanf("%s %d", str[i].name, &tmp);
for (int j=0; j<tmp; ++j) {
scanf("%d", &k);
++cnt[k];
buf[k].push_back(i);
}
}
sort(str+1, str+1+N, mycmp);
vector<int>::iterator itr;
for (int i=1; i<=K; ++i) {
printf("%d %d\n", i, cnt[i]);
for (itr = buf[i].begin(); itr != buf[i].end(); ++itr) {//将学生进行标记
bucket[*itr] = 1;
}
for (int j=1; j<=N; ++j) {//遍历一遍学生,若标记过则输出
if (bucket[str[j].id]) {
printf("%s\n", str[j].name);
}
}
for (itr = buf[i].begin(); itr != buf[i].end(); ++itr) {
bucket[*itr] = 0;
}
}
return 0;
}