首页 > 试题广场 >

Student List for Course (25)

[编程题]Student List for Course (25)
  • 热度指数:1996 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
Zhejiang University has 40000 students and provides 2500 courses. Now given the registered course list of each student, you are supposed to output the student name lists of all the courses.

输入描述:
Each input file contains one test case.  For each case, the first line contains 2 numbers: N (<=40000), the total number of students, and K (<=2500), the total number of courses.  Then N lines follow, each contains a student's name (3 capital English letters plus a one-digit number), a positive number C (<=20) which is the number of courses that this student has registered, and then followed by C course numbers.  For the sake of simplicity, the courses are numbered from 1 to K.


输出描述:
For each test case, print the student name lists of all the courses in increasing order of the course numbers.  For each course, first print in one line the course number and the number of registered students, separated by a space.  Then output the students' names in alphabetical order.  Each name occupies a line.
示例1

输入

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
#include <iostream> 
#include <vector>
#include <cstring> 
#include <algorithm> 
using namespace std;

const int MAXN = 40003;
const int MAXC = 2503;
char name[MAXN][5];
vector<int> course[MAXC];

bool cmp(int a, int b)
{     return strcmp(name[a], name[b]) < 0;
}

int main()
{     int N,K,C;     scanf("%d%d", &N, &K);     for(int i=0;i<N;i++)     {         scanf("%s %d", name[i], &C);         for(int j=0;j<C;j++)         {             int id;             scanf("%d", &id);             course[id].push_back(i);         }     }     for(int i=1;i<=K;i++)     {         printf("%d %d\n", i, course[i].size());         sort(course[i].begin(), course[i].end(), cmp);         for(int j=0;j<course[i].size();j++)             printf("%s\n", name[course[i][j]]);     }     return 0;
}

发表于 2018-03-15 01:27:15 回复(0)
善用stl,一遍过
#include <iostream>
#include <set>
#include <string>
using namespace std;

#define MAX 40009

int N, K, C;
set<string> a[3000];

int main()
{
    cin >> N >> K; string name;
    for (int i = 0; i < N; ++i) {
        cin >> name >> C; int lesson;
        for (int j = 0; j < C; ++j) {
            cin >> lesson;
            a[lesson].insert(name);
        }
    }
    for (int i = 1; i <= K; ++i) {
        if (!a[i].empty()) {
            int len = (int)a[i].size();
            cout << i << " " << len << endl;
            for (auto it = a[i].begin(); it != a[i].end(); ) {
                cout << *it; if (++it != a[i].end())cout << endl;
            }
        }
        if (i < K && !a[i + 1].empty())cout << endl;
    }
    return 0;
}


发表于 2021-03-04 08:29:03 回复(0)
我的代码在牛客全通过了,但是PAT最后一个测试点总显示答案错误。有哪位同学帮忙看一下吗。
我的思路是将人名的前三个字母编码展开成数字:26*(26*(第一个字母-‘A’ )+(第二个字母-‘A’))+(第三个字母-‘A’),放在26*26*26的数组里面,再从数组里面按顺序提取课程相信。这样就避免了大量的排序操作,虽然空间开支会很大。对于前三个字母重复的情况,推测是少数情况,所以额外在此处处理为map映射表储存多个字母重复的课程信息。
#include <iostream>
#include <map>
#include <vector>
using namespace std;
const int MAX_NUM = 26 * 26 * 26;
struct Stu {
    bool single = true;
    string name = "";
    vector<bool> course;
    map<string, vector<bool>> repeat;
};
struct Cou {
    int cnt = 0;
    vector<string> names;
};
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N, K;
    int max_lv = -1, min_lv = INT16_MAX;
    cin >> N >> K;
    vector<Stu> s(MAX_NUM);
    vector<int> cnt(K, 0);
    for (int i = 0; i < N; ++i) {
        string name;
        cin >> name;
        int n;
        cin >> n;
        int t_id = 26 * (26 * (name[0] - 'A') + (name[1] - 'A')) + name[2] - 'A';
        if (t_id > max_lv)
            max_lv = t_id;
        if (t_id < min_lv)
            min_lv = t_id;
        if (s[t_id].name == "") {
            s[t_id].name = name;
            s[t_id].course = vector<bool>(K, false);

        } else {
            if (s[t_id].single) {
                s[t_id].single = false;
                s[t_id].repeat[s[t_id].name].swap(s[t_id].course);
            }
            s[t_id].repeat[name] = vector<bool>(K, false);
        }
        for (int j = 0; j < n; ++j) {
            int id;
            cin >> id;
            if (s[t_id].single)
                s[t_id].course[id - 1] = true;
            else
                s[t_id].repeat[name][id - 1] = true;
            cnt[id - 1]++;
        }
    }
    vector<Cou> c(K);
    for (int i = 0; i < K; ++i) {
        c[i].names.resize(cnt[i], "");
    }
    for (int i = min_lv; i <= max_lv; ++i) {
        if (s[i].name == "")
            continue;
        if (s[i].single) {
            for (int j = 0; j < K; ++j) {
                if (s[i].course[j]) {
                    c[j].names[c[j].cnt++] = s[i].name;
                }
            }
        } else {
            for (auto m = s[i].repeat.begin(); m != s[i].repeat.end(); ++m) {
                for (int j = 0; j < K; ++j) {
                    if (m->second[j]) {
                        c[j].names[c[j].cnt++] = m->first;
                    }
                }
            }
        }
    }
    for (int i = 0; i < K; ++i) {
        cout << i + 1 << " " << c[i].cnt << "\n";
        for (int j = 0; j < c[i].cnt; ++j) {
            cout << c[i].names[j] << "\n";
        }
    }
    return 0;
}


发表于 2020-11-01 18:22:12 回复(0)
a = list(map(int,input().split()))
m = [[] for i in range(a[1] + 1)]
for i in range(a[0]):
    b = input().split()
    for j in b[2:]:
        m[int(j)].append(b[0])
        
for i in range(1,a[1] + 1):
    print('\n'.join([str(i) + ' ' + str(len(m[i]))] + sorted(m[i])))
都快1秒了还没超时

编辑于 2020-02-25 17:06:39 回复(1)
//牛客的全过,pat.4超时过不去
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
using namespace std;


//1047 Student List for Course
//课程从1~k编码
//注意1,有的课程可能没有学生,但也要输出0,不然pat.2过不去
//注意2,pat.4,使用string+cin会超时,改成char[]+scanf就可以了

//利用map和set的自动排序
map<int, set<string> *, less<int> > mp;
map<int, set<string> *>::iterator it;

int main() {
    int n, k, c, cid;
    string name;
    cin >> n >> k;

    //有的课程可能没有学生,但也要输出0
    for (int i = 0; i < k; ++i) {
        //为每一个课程初始化 
        set<string> *p = new set<string>;
        mp[i + 1] = p;
    }


    for (int i = 0; i < n; ++i) {
        char a[4];
        scanf("%s %d", a, &c);
        //cin>>name;
        //cin>>c;
        name = a;
        for (int j = 0; j < c; ++j) {
            //cin>>cid;
            scanf("%d", &cid);
            mp[cid]->insert(name);
        }
    }

    for (it = mp.begin(); it != mp.end(); ++it) {
        //sort(it->second.begin(),it->second.end());
        cout << it->first << " " << it->second->size() << endl;

        for (set<string>::iterator ii = it->second->begin(); ii != it->second->end(); ++ii) {
            cout << *ii << endl;
        }
    }

    return 0;
}

编辑于 2019-08-12 11:16:06 回复(0)
#include <iostream> 
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=40010;      //最大学生人数
const int maxc=2510;       //最大课程门数
char name[maxn][5];        //maxn个学生与其姓名
vector<int> course[maxc];  //course[i]存放第i门课的学生编号

bool cmp(int a,int b){
    return strcmp(name[a],name[b])<0; //按字典序对人名排序
}
int main(){
    int n,k,c,id;
    cin>>n>>k;
    for(int i=0;i<n;i++){
        scanf("%s %d",name[i],&c);
        for(int j=0;j<c;j++){
            scanf("%d",&id);
            course[id].push_back(i); //将学生i加入到id门课中
        }
    }
    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;
}

发表于 2018-03-06 00:02:02 回复(0)
//用string和cin会超时,所以名字要用char型数组,并且要自己写一个字符串比较函数
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 2500 + 2;

bool cmp(char* s1, char* s2){
    for (int i = 0; i < 4; i++){
        if(s1[i] < s2[i]){
            return true;
        }else if(s1[i] > s2[i]){
            return false;
        }
    }
    return true;
}

int main(){
    int n, k;
    scanf("%d %d", &n, &k);
    vector<char *> list[k + 1];
    for (int i = 0; i < n; ++i){
        char *name = new char[4];
        // char name[4];
        int c = 0;
        scanf("%s %d", name, &c);
        for (int j = 0; j < c; ++j){
            int course = 0;
            scanf("%d", &course);
            list[course].push_back(name);
        }
    }

    for (int i = 1; i <= k; ++i){
        printf("%d %d\n", i, list[i].size());
        sort(list[i].begin(), list[i].end(), cmp);
        for (int j = 0; j < list[i].size(); ++j)
            printf("%s\n", list[i][j]);
    }
    return 0;
}

发表于 2018-01-31 16:13:49 回复(3)
#include<bits/stdc++.h>
using namespace std;

vector<string> course[2510];

int main() {
    ios::sync_with_stdio(false);
	string name;
	int n,m;
	cin>>n>>m;
	for(int i=0; i<n; i++) {
		cin>>name;
		int k,x;
		cin>>k;
		for(int j=0; j<k; j++) {
			cin>>x;
			course[x].emplace_back(name);
		}
	}
	for(int i=1; i<=m; i++) {
		int l=course[i].size();
		sort(course[i].begin(),course[i].end());
		cout<<i<<" "<<l<<endl;
		for(int j=0; j<l; j++) {
			cout<<course[i][j]<<endl;
		}
	}
	return 0;
}

发表于 2022-11-19 11:31:29 回复(2)
我就不看!!
#include<iostream>
#include<map>
#include<set>
#include<string>
using namespace std;
int n,k,m,course;
string id;
map<int,set<string>> Hash;
int main(){
	scanf("%d%d", &n, &k);
	for(int i=0;i<n;i++){
		cin>>id>>m;
		for(int j=0;j<m;j++){
			scanf("%d", &course);
			Hash[course].insert(id);
		}
	}
	for(int i=1;i<=k;i++){
		printf("%d %d\n",i,Hash[i].size());
		for(auto it=Hash[i].begin();it!=Hash[i].end();it++)
			cout<<*it<<endl;
	}
	return 0;
}

发表于 2021-02-07 14:16:12 回复(0)

数字看错了,怪不得超界了

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

string str = "";
int n = 0, k = 0, clazzNum = 0, c = 0;
vector<string> p[2501];
bool com(string a,string b) {
    return a < b;
}
int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        cin >> str >> clazzNum;
        for (int j = 1; j <= clazzNum; j++) {
            scanf("%d",&c);
            p[c].push_back(str);
        }
    }
    for (int i = 0; i <=k; i++) {//对每个课程的姓名按字母表排序
        sort(p[i].begin(), p[i].end(),com);
    }
    for (int i = 1; i <= k; i++) {
        printf("%d %d\n",i,p[i].size());
        for (auto it = p[i].begin(); it != p[i].end(); it++)printf("%s\n",(*it).c_str());
    }
    system("pause");
    return 0;
}
发表于 2019-10-21 21:16:23 回复(0)
n,m = map(int,input().split())
lst = [[] for i in range(0,m+1)]
for i in range(n):
    temp = input().split()
    tem = list(map(int,temp[2:]))
    for i in tem:
        lst[i].append(temp[0])
for i in range(1,m+1):
    print(i,len(lst[i]))
    lst[i].sort()
    for j in lst[i]:
        print(j)

发表于 2018-12-07 20:41:52 回复(0)
N,M=map(int,input().split())
student=[input().split() for _ in range(N)]
course=[[] for _ in range(M+1)]
for x in student:
    for y in x[2:]:
        course[int(y)].append(x[0])
for i in range(1,len(course)):
    course[i].sort()
    print(i,len(course[i]))
    print('\n'.join(course[i]))

发表于 2018-09-04 07:31:25 回复(0)
思路:deque<string> v[2500] 做一个这个字符串数组,然后排序输出。
#include <iostream>
#include <fstream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;

#ifndef debug
ifstream ifile("case.txt");
#define cin ifile
#endif

int main()
{
    int    stuNum, courseNum;
    while (cin >> stuNum >> courseNum)
    {
        deque<string> v[2500];
        for (int i = 0; i < stuNum; i++)
        {
            string name;
            int chooseClass = 0;
            cin >> name >> chooseClass;
            for (int j = 0; j < chooseClass; j++)
            {
                int tmp;
                cin >> tmp;
                v[tmp - 1].push_back(name);
            }
        }
        // 输入完毕
        for (int j = 0; j < courseNum; j++)
        {
            cout << j + 1 << " " << v[j].size() << endl;;
            sort(v[j].begin(), v[j].end());
            for (int i = 0; i < v[j].size(); i++)
            {
                cout << v[j][i] << endl;
            }
        }
    }
    system("pause");
}

发表于 2018-08-28 21:08:17 回复(0)
#define DEBUG
#define _CRT_SECURE_NO_WARNINGS  
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
#ifdef DEBUG
    freopen("data.txt", "r", stdin);
#endif
    int i, j;
    int n, m;
    cin >> n >> m;
    vector<vector<string> > courses(m + 1,vector<string>(0));
    for (i = 0; i < n; i++) {
        string name;
        int nc, c;
        cin >> name;
        cin >> nc;
        for (j = 0; j < nc; j++) {
            cin >> c;
            courses[c].push_back(name);
        }
    }
    for (i = 1; i < courses.size(); i++) {
        cout << i << ' ' << courses[i].size() << endl;
        sort(courses[i].begin(), courses[i].end());
        for (j = 0; j < courses[i].size(); j++) {
            cout << courses[i][j] << endl;
        }
    }
#ifdef DEBUG
    freopen("CON", "r", stdin);
    getchar();
#endif
    return 0;
}

//二维vector,直接存名字,排序输出,也能过。
发表于 2018-08-14 10:14:42 回复(0)

//有没有大牛能帮小弟看看错在哪里,很简单的思路,本地也能跑通,提交就错
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
//#include<map>
//#include<stdio.h>
using namespace std;


struct Course{
    vector<char *> name;
};
Course courses[2502];
bool cmp(char * n1,char * n2){
    int result=strcmp(n1,n2);
    if(result==-1) return true;
    else return false;
}
int n,k;
int main(){
    scanf("%d %d",&n,&k);
    int i,j;
    char name[40002][5];
    int num;
    int id;
    for(i=0;i<n;i++){
        scanf("%s %d",name[i],&num);
        for(j=0;j<num;j++){
            scanf("%d",&id);
            courses[id].name.push_back(name[i]);
        }
    }
    int size;
    for(i=1;i<=k;i++){
        //list=courses[i].name;
        if(courses[i].name.empty()){
            printf("%d %d\n",i,0);
            continue;
        }
        size=courses[i].name.size();
        sort(courses[i].name.begin(),courses[i].name.end(),cmp);
        printf("%d %d\n",i,size);
        for(j=0;j<size;j++){
            printf("%s\n",courses[i].name[j]);
        }
    }
    system("pause");
    return 0;
}
编辑于 2017-11-28 13:47:58 回复(3)
#include<bits/stdc++.h>
using namespace std;
int main(){
    
    int N,K;
    cin>>N>>K;
    
    vector<set<string>> cor_reg(K+1);//利用set的自动排序
    
    for(int i=0;i<N;i++){
        string name;
        cin>>name;
        
        int C;
        cin>>C;
        for(int j=0;j<C;j++){
            int cNum;
            cin>>cNum;
            cor_reg[cNum].insert(name);
        }
        
    }
    
    
    for(int i=1;i<K+1;i++){
        cout<<i<<" "<<cor_reg[i].size()<<endl;
        //sort(cor_reg[i].begin(),cor_reg[i].end());//这个排序太久,有一个用例通不过
        
        for(set<string>::iterator it=cor_reg[i].begin();it!=cor_reg[i].end();it++){
            cout<<*it<<endl;
        }
        
        
    }
    
    
    return 0;
}

发表于 2017-07-21 15:29:12 回复(0)
#include "iostream"
#include "vector"
#include "string"
#include "cstring"
#include "queue"
#include "stack"
#include "map"
#include "ctime"
#include <limits.h>
#include <algorithm>
using namespace std;

int main()
{
int N, K;
string s;
cin >> N >> K;
vector<vector<string>> Course(K + 1);
for (int i = 0; i < N; i++)
{
cin >> s;
int n;
cin >> n;
for (int j = 0; j < n; j++)
{
int c;
cin >> c;
Course[c].push_back(s);
}
}
for (int i = 1; i <= K; i++)
{
cout << i << ' ' << Course[i].size()<<'\n';
sort(Course[i].begin(), Course[i].end());
for (int j = 0; j < Course[i].size(); j++)
cout << Course[i][j] << '\n';
}
}

发表于 2017-03-23 19:23:14 回复(0)
__author__ = 'Yaicky'
import time
class Student:
    def __init__(self, name, course):
        self.name = name
        self.course = course

    def __cmp__(self, other):
        return cmp(self.name, other.name)


while True:
    try:

        n, k = map(int, raw_input().strip().split())

        students = []
        studentnum = [0]*(k+1)
        for i in range(n):
            basestring = raw_input().strip().split()
            name, course = basestring[0], map(int, basestring[2:])
            for i in course:
                studentnum[i] += 1
            students.append(Student(name,course))

        students.sort()
        for i in range(1, k+1):
            print i, studentnum[i]
            for stutmp in students:
                if i in stutmp.course:
                    print stutmp.name
        
  

    except:
        break
#本地测试没问题  提交出现内部错误 不知道怎么解决-.-   感觉还是要尽可能少的排序吧,所以把
#所有学生按name排序了,然后遍历五次 在这门课就打印  不然的话应该要对同一课程排序name
#就要5次排序了 不过效率还是不高-.-  

编辑于 2016-07-22 11:11:56 回复(0)
java最后一个超时
import java.util.Scanner;
import java.util.TreeSet;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();//N (<=40000), the total number of students
        int k = in.nextInt();//K (<=2500), the total number of courses.
        TreeSet[] courses = new TreeSet[2501];
        for(int i = 0;i<n;i++){
            String name = in.next();
            String[] info = in.nextLine().split(" ");
            int cs = Integer.parseInt(info[1]);
            for(int j = 2;j<cs+2;j++){
                int cno = Integer.parseInt(info[j]);
                if(courses[cno]==null)
                    courses[cno] = new TreeSet<String>();
                courses[cno].add(name);
            }
        }
        for(int i = 1;i<courses.length;i++){
            TreeSet<String> course = courses[i];
            if(course!=null){
                System.out.println(i+" "+course.size());
                for (String name : course) {
                    System.out.println(name);
                }
            }
        }
    }
}
解题报告的方法也超时
public class Main{
	private static int[] all = new int[800002];
	private static int total = 0;
	private static String[] names = new String[40002];
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int k = in.nextInt();
		
		for(int i = 0;i<n;i++){
            names[i] = in.next();
            int cs = in.nextInt();
            for(int j = 0;j<cs;j++){
                all[total++] = (in.nextInt() << 16) | i;
            }
        }
		Arrays.sort(all, 0, total);
		for(int i = 1;i<=k;i++){
			System.out.print(i);
			int y = find1(i<<16);
			if(y<0 || (all[y]>>16) > i){
				System.out.print(" 0");
			}else{
				int x = find2(y,(i<<16) | (n-1));
				int size = x-y+1;
				System.out.println(" "+size);
				if(size<=0)
					continue;
				String[] temp = new String[size];
				for(;y<=x;y++){
					temp[--size] = (names[ all[y] & 65535 ]);
				}
				Arrays.sort(temp);
				for (String string : temp) {
					System.out.println(string);
				}
			}
		}
	}
	private static int find1(int x){
		int left = 0;
		int right = total-1;
		int r = -1;
		while(left<=right){
			int mid = (left+right)/2;
			if(all[mid]>=x){
				r = mid;
				right = mid-1;
			}else{
				left = mid +1;
			}
		}
		return r;
	}
	private static int find2(int left,int x){
		int right = total -1;
		left++;
		while(left <= right){
			int mid = (left + right) /2;
			if(all[mid]<=x)
				left = mid + 1;
			else
				right = mid -1;
		}
		return left - 1;
	}
}

发表于 2016-07-20 19:14:41 回复(0)