-
题目大意:PAT考生号的第1个字母代表考生等级,第2-4个数字代表考试地点,第5-10个数字代表yymmdd格式的时间,第11-13位表示考生数量(0-999)。给出一些PAT考生号,根据查询输出信息:
- 按分数降序输出所给等级所有的考生分数,如果分数相同,按考生号以字母表顺序升序排序(即直接比较两个字符串)
- 输出所给地点所有的考生数量和他们的总分
- 输出所给日期里每个地点的所有考生数量,按考生数量降序排序,若考生数量相同,就按地点升序排序(即直接比较两个字符串)
-
思路:
- 用结构体数组(vector)记录所有考生,结构体包括学生的考号和成绩
1. class 1:找到查询等级的所有学生,按分数降序输出号码 和 分数,若分数相同,就按考生号的字母表顺序升序输出(即直接比较)
2. class 2:找到查询地点的所有学生,计算学生的总数和总成绩
3. class 3:找出查询日期里各个地区的所有学生的个数,用一个map存地址和数量(按考生数量降序排序,若考生数量相同,就按地点数升序排序) - 再用一个新的vector记录查询到的考生
- 用结构体数组(vector)记录所有考生,结构体包括学生的考号和成绩
-
知识点:
- 结构体
- STL容器
- string
- vector
- map
- 遍历容器的方法
- 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; }
-
总结:
-
结构体
- 增加一个元素:
{it.first, it.second}
- 增加一个元素:
-
STL容器
-
string
-
vector
- 初始化:
vector<int> v;
- 初始化时定义大小后会初始化为0,不定义大小就不会初始化为0;
- 在v的最后插入一个新元素:
v.push_back(i)
;
- 初始化:
-
map
- 初始化:
map<string, int> m;
- 定义后所有value被初始化为0
- 初始化:
-
遍历容器的方法
-
使用迭代器遍历:
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⾥⾯的新特性,可以让编译器根据初始值类型直接推断变量的类型
-
基于范围(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;
-
-
-
sort()、自定义cmp
- 需
#include <algorithm>
- 注意传入cmp的变量都是地址;
- 升序:
a > b
;降序:a < b
。
- 需
-
若运行超时,可能是用了
cout
,改成printf()
一般就能解决问题。 -
if()
里有多个判断条件记得要打括号!
-
【PAT】1153 Decode Registration Card of PAT (25 分)
最新推荐文章于 2021-12-08 17:04:39 发布