PAT 1050 Course List for Student (25)(选课)

本文介绍了一个学生课程注册查询系统的实现方法,该系统能够快速响应学生的查询请求,并展示其注册的所有课程。通过使用C++及标准模板库,系统有效地处理了大量学生和课程的数据。

题目

1039. Course List for Student (25)

时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue
Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=40000), the number of students who look for their course lists, and K (<=2500), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students Ni (<= 200) are given in a line. Then in the next line, Ni student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.

Output Specification:

For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student's name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.

Sample Input:
11 5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6 NON9
Sample Output:
ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0

解题思路

  • 1.会用map<int, vector<int> > student就行了,用它先保存在输出就行了,注意:直接用map<string, vector<int> > student会超时。

代码

  • 1.下面这个居然还会超时,共220毫秒
#include <iostream>
#include<map>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;
int n,k;
int w[] = {1,26,26 * 26,26 * 26 * 26};
int make(string p)
{
    return (p[3] - '0') * w[0] + (p[2] - 'A') * w[1] + (p[1] - 'A') * w[2] + (p[0] - 'A') * w[3];
}
map<int,vector<int> > student;
int main()
{
    cin >> n >> k;
    for (int i = 0; i < k; ++i) {
        int tem_course,numOfstu;
        cin >> tem_course >> numOfstu;
        for (int j = 0; j < numOfstu; ++j) {
            string strname;
            cin >> strname;
            int name =make(strname);
            student[name].push_back(tem_course);
        }
    }
    for (int i = 0; i < n; ++i) {
        string str_name;
       // tem_name.empty()
        cin >> str_name;
        int tem_name = make(str_name);
        vector<int> tem_course = student[tem_name];
        cout << str_name << " " << tem_course.size();
        if (!tem_course.empty()) {
            sort(tem_course.begin(),tem_course.end());
            for (int j = 0; j < tem_course.size(); ++j) {
                cout<<" "<< tem_course[j];
            }
        }
        cout << endl;

    }
    return 0;
}
  • 2.这个不会超时,时间出奇的少。
#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
map<int,vector<int> > mp;
int w[] = {1,26,26 * 26,26 * 26 * 26};
int make(char *p)
{
    return (p[3] - '0') * w[0] + (p[2] - 'A') * w[1] + (p[1] - 'A') * w[2] + (p[0] - 'A') * w[3];
}
int main()
{
    int n,k,i,j;
    scanf("%d%d",&n,&k);
    char name[6];
    for(i = 0; i < k; i++)
    {
        int c_num,s_num;
        scanf("%d%d",&c_num,&s_num);
        for(j = 0; j < s_num; j++)
        {
            scanf("%s",name);
            mp[make(name)].push_back(c_num);
        }
    }
    for(i = 0; i < n; i++)
    {
        scanf("%s",name);
        int ss = make(name);
        if(mp.find(ss) != mp.end())
        {
            sort(mp[ss].begin(),mp[ss].end());
            printf("%s %d",name,mp[ss].size());
            for(j = 0; j < mp[ss].size(); j++)
                printf(" %d",mp[ss][j]);
            puts("");
        }
        else
        {
            printf("%s 0\n",name);
        }
    }
    return 0;
}
### 关于PAT 1050 C语言解决方案 #### 题目解析 题目要求实现一个程序,计算给定正整数按照特定规则变换到 `1` 所需的步数。以下是具体逻辑分析: - 如果当前数值为奇数,则将其更新为 `(3 * n + 1) / 2`。 - 如果当前数值为偶数,则将其更新为 `n / 2`。 - 记录每次操作所需的总次数。 最终输出从初始值到达 `1` 的操作总数。 --- #### 完整代码实现 以下是一个完整的 C 语言实现版本[^1]: ```c #include <stdio.h> int main() { int n, count = 0; // 输入验证部分 if (scanf("%d", &n) != 1 || n > 1000 || n <= 0) { printf("请输入一个小于等于1000的正整数"); return 1; } while (n != 1) { if (n % 2 == 1) { // 奇数情况 n = (3 * n + 1) / 2; } else { // 偶数情况 n /= 2; } count++; } printf("%d\n", count); return 0; } ``` 上述代码实现了输入校验功能以及核心算法逻辑,并确保满足题目中的约束条件。 --- #### 测试样例说明 为了测试该程序的功能是否正确,可以设计以下几个典型测试用例[^2]: | **输入** | **预期输出** | |----------|--------------| | `9` | `7` | | `8` | `3` | | `1` | `0` | 解释: - 对于输入 `9`,经过多次转换后得到序列:`9 -> 14 -> 7 -> 11 -> 17 -> 26 -> 13 -> 20 -> 10 -> 5 -> 8 -> 4 -> 2 -> 1`,共经历 `7` 步。 - 对于输入 `8`,其路径为:`8 -> 4 -> 2 -> 1`,仅需 `3` 步即可完成。 --- #### 可能扩展方向 如果希望进一步优化或者增强此题目的适用范围,可以从以下方面入手[^3]: - 添加异常处理机制以应对非法输入(如负数或浮点数)。 - 改造函数化结构以便复用性和可读性的提升。 - 提供多组数据批量处理能力支持更复杂的场景需求。 --- #### 进阶思考 对于类似的数学运算类问题,在实际开发过程中需要注意边界条件控制和性能调优等问题[^4]。例如本题中涉及大量除法与取模操作可能带来效率瓶颈;另外还需考虑大数溢出风险等因素影响程序稳定性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值