题196.pat甲级练习-1047 Student List for Course (25 分)


题196.pat甲级练习-1047 Student List for Course (25 分)


一、题目

在这里插入图片描述
在这里插入图片描述

二、题解

输入时将名字入到对应课程表示的容器下就好,最最需要注意的是,输入输出只能想办法用scanf和printf,不然一定会超时。下面是用set来装人名的代码,仍然超时了就是了,后面会给出正确代码。

//用set仍然超时,insert会多耗时间的
#include <bits/stdc++.h>

using namespace std;

set<string> s[2501];

int main()
{
    int N,K;
    scanf("%d%d",&N,&K);
    for(int i=0;i<N;i++)
    {
        char name[5];//为避免超时,所以我输入只能用scanf,所以不得不用char []
        scanf("%s",name);
        int C;
        scanf("%d",&C);
        for(int j=0;j<C;j++)
        {
            int course;
            scanf("%d",&course);
            s[course].insert(name);//string(char[]),可将char[]通过构造方法变成string。这里直接insert就好,因为set<string>
        }
    }
    for(int i=1;i<=K;i++)
    {
        printf("%d %d\n",i,s[i].size());//输出课程编号和课程人数
        for(auto it=s[i].begin();it!=s[i].end();it++)
        {
            printf("%s\n",(*it).c_str());//将string用.c_str()转成char[]用printf输出,不能用cout否则会超时
        }
    }
}

把set改成vector去装,之后排序就好了。代码如下:

#include <bits/stdc++.h>

using namespace std;

vector<string> v[2501];

int main()
{
    int N,K;
    cin>>N>>K;
    for(int i=0;i<N;i++)
    {
        char name[5];
        scanf("%s",name);
        int C;
        scanf("%d",&C);
        for(int j=0;j<C;j++)
        {
            int c;
            scanf("%d",&c);
            v[c].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(int j=0;j<v[i].size();j++)
        {
            printf("%s\n",v[i][j].c_str());
        }
    }
}

用set不超时(巧用运算符重载,在输入时就做好排序,后期直接倒腾,不必再字典排序),可以这么干,代码如下:

/*
#include <bits/stdc++.h>

using namespace std;
struct stuInfo{
    char name[5];
    int C;
    int course[20];
    bool operator < (const stuInfo &x) const{
        return strcmp(name,x.name) <= 0;
    }
    bool operator > (const stuInfo &x) const
    {
        return strcmp(name, x.name) >= 0;
    }
    bool operator == (const stuInfo &x) const
    {
        return strcmp(name, x.name) == 0;
    }
};
set<stuInfo> s;
vector<string> courses[2501];
int main()
{
    int N, K;
    scanf("%d%d", &N, &K);
    stuInfo *stu;
    for (int i = 0; i < N; i++)
    {
        stu=new stuInfo();
        scanf("%s", stu->name);
        scanf("%d", &stu->C);
        for (int j = 0; j < stu->C; j++)
        {
            scanf("%d", stu->course+j);
        }
        s.insert(*stu);
    }
    for(auto it=s.begin();it!=s.end();it++)//由于前面insert操作把名字按字典序排好了所以这里直接倒腾
    {
        for(int i=0;i<it->C;i++)//访问那个人结构体,将它选的课程插入他的名字(不用担心课程的人名字字典序了,因为字典序在前的会先被拿来插入)
        {
            courses[it->course[i]].push_back(it->name);
        }
    }
    for (int i = 1; i <= K; i++)
    {
        printf("%d %d\n", i, courses[i].size()); //输出课程编号和课程人数
        for (auto it = courses[i].begin(); it != courses[i].end(); it++)
        {
            printf("%s\n", (*it).c_str()); //将string用.c_str()转成char[]用printf输出,不能用cout否则会超时
        }
    }
}
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值