【PAT】1047 Student List for Course (25 分)

46 篇文章 0 订阅
44 篇文章 0 订阅
  • 题目大意:

  • 思路1:因为set会自动排序,所以用结构体数组存学生的课表,用结构体数组存每节课的学生(不用排序,因为是按照顺序输出课程)。

    超时了(用太多stl容器)

    • 知识点:

      1. 结构体
      2. set
      3. vector
    • 代码:

      #include <iostream>
      #include <set>
      #include <vector>
      using namespace std;
      
      struct stu{
          string name;
          set<int> crs;
      };
      
      struct course{
          int id;
          set<string> registered_stu; // set会自动排序
      };
      
      
      int main(){
          int n, k, c, cid;
          string name;
          scanf("%d %d", &n, &k);
          vector<stu> students(n);
          vector<course> courses(k);
          for(int i = 0; i < n; i++){
              cin >> name >> c;
              students[i].name = name;
              for(int j = 0; j < c; j++){
                  cin >> cid;
                  students[i].crs.insert(cid);
              }
          }
      
          for(int i = 0; i < k; i++){
              for(int j = 0; j < n; j++){
                  if(students[j].crs.find(i + 1) != students[j].crs.end()){    // 这个学生选了该课
                      courses[i].id = i + 1;
                      courses[i].registered_stu.insert(students[j].name);
                  }
              }
          }
      
          for(int i = 0; i < k; i++){
              printf("%d %d\n", i + 1, courses[i].registered_stu.size());  // 输出courses[i].id时答案错误,因为如果没有学生选这个课,就没有course[i].id
              for(auto j = courses[i].registered_stu.begin(); j != courses[i].registered_stu.end(); j++){
                  printf("%s\n", (*j).c_str());
              }
          }
          return 0;
      }
      
  • 思路2:用二维数组course[i][j]存选每节课的学生,course[i]表示第i+1节课,course[i][j]表示选该课的学生id。 然后再用sort()给每个course[i]排序。

    如果用集合数组(set<string> student[2510])还是超时,因为用了set

    • 知识点:

      1. 二维数组
      2. vector
      3. 排序
    • 代码:

      #include <iostream>
      #include <string>
      #include <vector>
      #include <algorithm>
      using namespace std;
      
      vector<string> courses[2510];   // 二维数组,因为每节课学生的数量不确定,所以用set,方便插入元素
      
      bool cmp(string stu1, string stu2){
          return stu1 < stu2;
      }
      
      int main(){
          int n, k, c, cid, i, j;
          scanf("%d %d", &n, &k);
          for(i = 0; i < n; i++){
              string student;
              cin >> student >> c;
              for(j = 0; j < c; j++){
                  scanf("%d", &cid);
                  courses[cid].push_back(student);
              }
          }
      
          for(i = 1; i <= k; i++){
              printf("%d %d\n", i, courses[i].size());
              sort(courses[i].begin(), courses[i].end(), cmp);
              for(auto it = courses[i].begin(); it != courses[i].end(); it++)
                  printf("%s\n", (*it).c_str());
          }
          return 0;
      }
      
  • 总结:

    1. 又理解错了题意。"print the student name lists of all the courses in increasing order of the course numbers" 应该是按照字典序升序输出各个课程的学生,我却理解成了按照学生数升序输出各个课程的学生。

      以后应该更仔细一点!

    2. set太耗时了。我已经做到好几道题因为用了set而超时了。

      • set内部由红黑树(一种平衡二叉查找树)实现,unordered_set散列实现,所以**unordered_set速度比set快得多**。
      • map内部也由红黑树(一种平衡二叉查找树)实现,unordered_map由散列实现,所以**unordered_map速度比set快得多**。
    3. 二维数组:

      1. int a[10][10]

      2. vector<int> a[10]

      3. char a[10][10]:字符串数组

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值