【PAT】1153 Decode Registration Card of PAT (25 分)

46 篇文章 0 订阅
44 篇文章 0 订阅
  • 题目大意:PAT考生号的第1个字母代表考生等级,第2-4个数字代表考试地点,第5-10个数字代表yymmdd格式的时间,第11-13位表示考生数量(0-999)。给出一些PAT考生号,根据查询输出信息:

    1. 按分数降序输出所给等级所有的考生分数,如果分数相同,按考生号以字母表顺序升序排序(即直接比较两个字符串)
    2. 输出所给地点所有的考生数量和他们的总分
    3. 输出所给日期里每个地点的所有考生数量,按考生数量降序排序,若考生数量相同,就按地点升序排序(即直接比较两个字符串)
  • 思路:

    1. 用结构体数组(vector)记录所有考生,结构体包括学生的考号和成绩
      1. class 1:找到查询等级的所有学生,按分数降序输出号码 和 分数,若分数相同,就按考生号的字母表顺序升序输出(即直接比较)
      2. class 2:找到查询地点的所有学生,计算学生的总数和总成绩
      3. class 3:找出查询日期里各个地区的所有学生的个数,用一个map存地址和数量(按考生数量降序排序,若考生数量相同,就按地点数升序排序)
    2. 再用一个新的vector记录查询到的考生
  • 知识点:

    1. 结构体
    2. STL容器
      1. string
      2. vector
      3. map
      4. 遍历容器的方法
    3. sort()、自定义cmp
  • 代码:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <map>
    #include <algorithm>
    using namespace std;
    
    struct testee{
        string number;
        int score;
    };
    bool cmp1(testee &t1, testee &t2){    // 注意传进来的是地址!
        if(t1.score != t2.score)
            return t1.score > t2.score;
        else
            return t1.number < t2.number;
    };
    
    int main(){
        int n, m;
        cin >> n >> m;
        vector<testee> t(n);    // 定义大小后会初始化为0
        int i, j;
        for(i = 0; i < n; i++)
            cin >> t[i].number >> t[i].score;   // 可以直接输入
        for(i = 0; i < m; i++){
            int cls, cnt = 0, sum = 0;;
            string query;
            vector<testee> v;   // 不定义大小就不会初始化为0
            cin >> cls >> query;
            printf("Case %d: %d %s\n", i + 1, cls, query.c_str());
            if(cls == 1){
                for(j = 0; j < n; j++)
                    if(t[j].number[0] == query[0])
                        v.push_back(t[j]);
                sort(v.begin(), v.end(), cmp1);
            }
            else if(cls == 2){
                for(j = 0; j < n; j++)
                    if(t[j].number.substr(1, 3) == query){
                        cnt++;
                        sum += t[j].score;
                    }
                if(cnt != 0)
                    printf("%d %d\n", cnt, sum);
            }
            else{
                map<string, int> m; // 值自动初始化为0
                for(j = 0; j < n; j++)
                    if(t[j].number.substr(4, 6) == query)
                        m[t[j].number.substr(1, 3)]++;
                for(auto it : m)    v.push_back({it.first, it.second});    // 遍历stl容器;{}是一个结构体
                sort(v.begin(), v.end(), cmp1);
            }
            for(auto it : v)
                printf("%s %d\n", it.number.c_str(), it.score); // 不能用cout输出,会超时!!!
            if(((cls == 1 || cls == 3) && v.empty()) || (cls == 2 && cnt == 0)) // 注意要打括号哦!!!
                printf("NA\n");
        }
        return 0;
    }
    
  • 总结:

    1. 结构体

      1. 增加一个元素:{it.first, it.second}
    2. STL容器

      1. string

      2. vector

        1. 初始化:vector<int> v;
          • 初始化时定义大小后会初始化为0,不定义大小就不会初始化为0;
        2. 在v的最后插入一个新元素:v.push_back(i)
      3. map

        1. 初始化:map<string, int> m;
          • 定义后所有value被初始化为0
      4. 遍历容器的方法

        1. 使用迭代器遍历v.begin()是⼀个指针,指向容器的第⼀个元素, v.end() 指向容器的最后⼀个元素的后⼀个位置,所以迭代器指针it 的for循环判断条件是it != v.end()

          vector<int> v = {1, 2, 3};
          for(auto it = v.begin(); it != v.end(); it++)	// auto相当于 vector<int>::iterator 的简写
              cout << *it << endl;
          
          • auto 是C++11⾥⾯的新特性,可以让编译器根据初始值类型直接推断变量的类型
        2. 基于范围(range-based)的for循环:遍历数组中的每个元素

          int a[3] = {1, 2, 3};
          for(int i : a)
              cout << i << endl;
          
          vector<int> v = {1, 2, 3};
          for(auto it : v)
              cout << it << endl;
          
    3. sort()、自定义cmp

      1. #include <algorithm>
      2. 注意传入cmp的变量都是地址
      3. 升序:a > b;降序:a < b
    4. 若运行超时,可能是用了cout,改成printf()一般就能解决问题。

    5. if()里有多个判断条件记得要打括号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值