数据结构实验之排序七:选课名单
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
随着学校规模的扩大,学生人数急剧增加,选课名单的输出也成为一个繁重的任务,我校目前有在校生3万多名,两千多门课程,请根据给定的学生选课清单输出每门课的选课学生名单。
输入
输入第一行给出两个正整数N( N ≤ 35000)和M(M ≤ 2000),其中N是全校学生总数,M是课程总数,随后给出N行,每行包括学生姓名拼音+学号后两位(字符串总长度小于10)、数字S代表该学生选课的总数,随后是S个课程编号,约定课程编号从1到M,数据之间以空格分隔。
输出
按课程编号递增的顺序输出课程编号、选课总人数以及选课学生名单,对选修同一门课程的学生按姓名的字典序输出学生名单。数据之间以空格分隔,行末不得有多余空格。
示例输入
5 3 Jack01 2 2 3 Jone01 2 1 3 Anni02 1 1 Harry01 2 1 3 TBH27 1 1
示例输出
1 4 Anni02 Harry01 Jone01 TBH27 2 1 Jack01 3 3 Harry01 Jack01 Jone01
方法一:根据课程建立结构体,里面存储选该课的人名和总次数。
#include <bits/stdc++.h>
#include <string.h>using namespace std;
struct Class
{
string name[350];//最大总人数是35000,经过测试,开到35000会超内存,而开到350,不会超也通过了。
int cot;
}Class[2100];
int main()
{
int n, m, i, j, s, a, h=0;
string name ;
int Num;
cin>>n>>m;
for(i=0;i<=m;i++)
{
Class[i].cot=0;//课程的总数都归零
}
for(i=0;i<n;i++)
{
cin>>name;
cin>>s;
for(j=0;j<s;j++)
{
cin>>a;
Class[a].name[ Class[a].cot ] = name;//记录名字
Class[a].cot++;//次数增加
}
}
for(i=0;i<m;i++)
{
cout<<i+1<<' ';
cout<<Class[i+1].cot<<endl;
sort(Class[i+1].name,Class[i+1].name+Class[i+1].cot);//将名字按字典序排好,sort用法去百度吧。
for(j=0;j<Class[i+1].cot;j++)
{
cout<<Class[i+1].name[j]<<endl;
}
}
}
方法二:根据学生来建结构体,内部存名字,和课程序号。运行是没问题的,但是提交超内存,就算像上面一样数组
改小,但会变成re。其他改进方法也试了,不行。so此路不通,但是还是记录下来吧。
#include <string.h>
using namespace std;
int Num[2010];
struct Message
{
string name;
int num[2010];
}Mes[35100];
void S ort(Message *M,int n,int m,int *s)
{
int i,j,h;
for(i=0;i<m;i++)//循环课程
{//用了3个for循环,方法不是很优
printf("%d ",i+1);
printf("%d\n",Num[i+1]);
for(j=0;j<n;j++)//循环学生
{
for(h=0;h<=s[j];h++)//循环个人选课num数组
{
if(M[j].num[h]==i+1)
{
cout<<M[j].name;
break;
}
}
}
}
}
int cmp (Message a,Message b){
return a.name<b.name;
}
int main()
{
int n,m,s[2010],i,j;
scanf("%d %d",&n,&m);
memset(Num,0,sizeof(Num));
for(i=0;i<n;i++)
{
cin>>Mes[i].name;
scanf("%d",&s[i]);
for(j=0;j<s[i];j++)
{
scanf("%d",Mes[i].num[j]);
Num[ Mes[i].num[j] ]++;
}
}
s ort (Mes,Mes+n, cmp );//输入完后,立即将他们按字典序排好 // 根据结构体的某成员(name)来排序结构体
S ort (Mes,n,m,s);
}