1095 解码PAT准考证 (25 point(s))
-
写的时候有几个问题,刚开始以为考场的数据和日期的相似而共用,但是测试的时候发现,同考场的不一定同日期。所以又新建了一个结构体来存日期相关的数据。
-
测试点一、二、四。
题干太长看得有点意识模糊。写的时候只考虑了类型 2 查询无果,而没有考虑类型 1 和 3 。所以要参考类型 2 多加一个查询判断。
我是用下面这个测试数据才发现自己忽略了这个判断的。
1 6 T101000101000 0 3 000101 2 101 1 T 1 A 1 B 3 180908 -
测试点三。
修改了上面的问题后剩下测试点三超时。又参考了其他文章,原来是老问题 cin cout 太慢了,改成 printf 和 scanf 即可。
-
看了下别人的写法。采用的思路是将学生的准考证号和成绩读取储存,针对不同类型的查询从储存的数据中提取数据,统计并排序。
这样写就可以不用像我这里定义多个结构体类型、容器及其内部排序。节省不少空间。
针对排序,虽然类型 1 3 的查询数据不一样,分别是 “准考证号 成绩” 和 “考场编号 总人数”,但可以看成一类数据 “id value”,所以别人的代码对这两个数据类型用了同一个排序函数,化简了不少代码空间。
想了想这样写的理由,因为所有查询的数据都出自学生的数据,所以可以根据查询类型截取准考证号不同部分统计,放入容器进行排序再输出。
这样就可以避免定义过多的结构体类型及容器,但不一定查询对应类型而浪费空间(无论从内存还是代码空间上)。
if (((num == 1 || num == 3) && ans.size() == 0) || (num == 2 && cnt == 0)) printf("NA\n");这种写法最后判断查询不存在,需要对不同查询类型及其统计的变量进行判断。
还有,如果不需要排序可以用 unordered_map 和 unordered_set 这样也可以按 key 映射但不会花时间排序。虽然不知道为什么我自己写的时候没有用到这两个东西,而他们都提到不用可能超时。
// 25 points
#include <bits/stdc++.h>
using namespace std;
struct Stu{
string id;
int score;
bool operator < (Stu s) const{
if(score != s.score) return score > s.score;
return id < s.id;
}
};
struct Room{
string id;
int score = 0, peo = 0;
bool operator < (Room r) const{
if(peo != r.peo) return peo > r.peo;
return id < r.id;
}
};
struct Date{
string id;
int peo = 0;
bool operator < (Room r) const{
if(peo != r.peo) return peo > r.peo;
return id < r.id;
}
};
int main() {
int N, M;
map<char, set<Stu>> stu;
map<string, Room> room;
map<string, map<string, Room>> date;
cin >> N >> M;
while(N--){
string id;
int score;
cin >> id;
scanf("%d", &score);
string roomID = id.substr(1, 3), datetmp = id.substr(4, 6);
// 类型1
stu[id[0]].insert({id, score});
// 类型2
room[roomID].id = roomID;
room[roomID].score += score;
room[roomID].peo++;
// 类型3
date[datetmp][roomID].id = roomID;
date[datetmp][roomID].peo++;
}
for(int i = 1; i <= M; i++){
int type; string obj;
cin >> type >> obj;
printf("Case %d: %d %s\n", i, type, obj.c_str());
if(type == 1){
if(stu.find(obj[0]) == stu.end())cout << "NA" << endl;
else
for(auto s: stu[obj[0]])
printf("%s %d\n", s.id.c_str(), s.score);
}
else if(type == 2){
if(room.find(obj) == room.end())cout << "NA" << endl;
else printf("%d %d\n", room[obj].peo, room[obj].score);
}
else{
if(date.find(obj) == date.end())cout << "NA" << endl;
else{
// 放入 set 集合排序
set<Room> out;
for(auto d: date[obj]) out.insert(d.second);
for(auto o: out)
printf("%s %d\n", o.id.c_str(), o.peo);
}
}
}
}
// 15 points
#include <bits/stdc++.h>
using namespace std;
struct Stu{
string id;
int score;
bool operator < (Stu s) const{
if(score != s.score) return score > s.score;
return id < s.id;
}
};
struct Room{
string id;
int score = 0, peo = 0;
bool operator < (Room r) const{
if(peo != r.peo) return peo > r.peo;
return id < r.id;
}
};
struct Date{
string id;
int peo = 0;
bool operator < (Room r) const{
if(peo != r.peo) return peo > r.peo;
return id < r.id;
}
};
int main() {
int N, M;
map<char, set<Stu>> stu;
map<string, Room> room;
map<string, map<string, Room>> date;
cin >> N >> M;
while(N--){
string id;
int score;
cin >> id >> score;
string roomID = id.substr(1, 3), datetmp = id.substr(4, 6);
// 类型1
stu[id[0]].insert({id, score});
// 类型2
room[roomID].id = roomID;
room[roomID].score += score;
room[roomID].peo++;
// 类型3
date[datetmp][roomID].id = roomID;
date[datetmp][roomID].peo++;
}
for(int i = 1; i <= M; i++){
int type; string obj;
cin >> type >> obj;
printf("Case %d: %d %s\n", i, type, obj.c_str());
if(type == 1){
for(auto s: stu[obj[0]])
cout << s.id << " " << s.score << endl;
}
else if(type == 2){
if(room.find(obj) == room.end())cout << "NA" << endl;
else cout << room[obj].peo << " " << room[obj].score << endl;
}
else{
// 放入 set 集合排序
set<Room> out;
for(auto d: date[obj]) out.insert(d.second);
for(auto o: out)
cout << o.id << " " << o.peo << endl;
}
}
}
浙公网安备 33010602011771号