目录
1,题目描述
Sample Input:
8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999
Sample Output:
Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA
题目大意
给出若干个考生的id(分为4部分,分别代表等级,座位号,日期,编号)、分数,以及不同类型的查询,输出查询对应的结果
type1:根据给出的考试等级,按顺序(成绩高的在前面,相同则id小的在前面)输出考生id及分数;
type2:根据给出的座位号,输出该座位上的人数,以及他们的分数总和;
type3:根据给定的日期,按顺序(人数多的排前面,人数相同则座位号小的排前面)输出座位号以及该座位号对应的人数;
2,思路
参考大佬的解法@日沉云起【pat甲级1153 Decode Registration Card of PAT、乙级1095 解码PAT准考证题解】
数据结构
- struct student{
string id, level;
int site, date, number, score;
}data[10005];存放每位考生的信息; - struct site{
int id, num;//id座位编号 num人数
};存放每个座位的信息; - map<int, int> record:用于type3类型的查询,遍历data,将对应座位上的人数加一,并将record中的数据再存入vector<site> ans中;
算法
数据结构设计好了之后,算法就很简单了;
type1.
type2.
type3.
3,AC代码
#include<bits/stdc++.h>
using namespace std;
int N, M;
struct student{
string id, level;
int site, date, number, score;
}data[10005];
struct site{
int id, num;//id座位编号 num人数
};
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d%d", &N, &M);
string s;
int x;
for(int i = 0; i < N; i++){
cin>>s>>x;
data[i] = {s, s.substr(0, 1), stoi(s.substr(1, 3)), stoi(s.substr(4, 6)), stoi(s.substr(11, 3)), x};
}
for(int k = 1; k <= M; k++){
cin>>x>>s;
printf("Case %d: %d %s\n", k, x, s.c_str());
if(x == 1){
vector<student> ans;
for(int i = 0; i < N; i++){
if(data[i].level == s)
ans.push_back(data[i]);
}
sort(ans.begin(), ans.end(), [](const student& a, const student& b){
if(a.score != b.score) return a.score > b.score;
else return a.id < b.id;
});
if(ans.size() == 0) printf("NA\n");
else{
for(auto it : ans){
printf("%s %d\n", it.id.c_str(), it.score);
}
}
}else if(x == 2){
int num = 0, totalScore = 0, pos = stoi(s); //pos特定位置
for(int i = 0; i < N; i++){
if(data[i].site == pos){
num++;
totalScore += data[i].score;
}
}
if(num == 0) printf("NA\n");
else printf("%d %d\n", num, totalScore);
}else{
int time = stoi(s); //特定时间
vector<site> ans;
map<int, int> record; //记录特定位置的人数
for(int i = 0; i < N; i++){
if(data[i].date == time)
record[data[i].site]++;
}
for(auto it : record)
ans.push_back({it.first, it.second});
sort(ans.begin(), ans.end(), [](const site& a, const site& b){
if(a.num != b.num)
return a.num > b.num;
else
return a.id < b.id;
});
if(ans.size() == 0) printf("NA\n");
else{
for(auto it : ans){
printf("%d %d\n", it.id, it.num);
}
}
}
}
return 0;
}
4,解题过程
第一搏
将所有数据存到data中(id,score),每次查询遍历data取出符合条件的元素放入相应的结构体容器中,按照规则排序输出
#include<bits/stdc++.h>
using namespace std;
int N, M;
struct type1{
string id;
int score;
}data[10005];
struct type3{
string site;
int num;
};
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d%d", &N, &M);
string s;
int x;
for(int i = 0; i < N; i++){
cin>>s>>x;
data[i] = {s, x};
}
for(int k = 1; k <= M; k++){
cin>>x>>s;
printf("Case %d: %d %s\n", k, x, s.c_str());
if(x == 1){
vector<type1> ans;
for(int i = 0; i < N; i++){
if(data[i].id.substr(0, 1) == s)
ans.push_back(data[i]);
}
sort(ans.begin(), ans.end(), [](const type1& a, const type1& b){
if(a.score != b.score)
return a.score > b.score;
else
return a.id < b.id;
});
if(ans.size() == 0) printf("NA\n");
else{
for(auto it : ans){
printf("%s %d\n", it.id.c_str(), it.score);
}
}
}else if(x == 2){
int num = 0, totalScore = 0;
//string s1 = s.substr(1, 3);
for(int i = 0; i < N; i++){
//cout<<s1<< ' '<< data[i].id.substr(1, 3)<<endl;
if(s == data[i].id.substr(1, 3)){
num++;
totalScore += data[i].score;
}
}
if(num == 0) printf("NA\n");
else printf("%d %d\n", num, totalScore);
}else{
vector<type3> ans;
map<string, int> record;
for(int i = 0; i < N; i++){
if(s == data[i].id.substr(4, 6))
record[data[i].id.substr(1, 3)]++;
}
for(auto it : record)
ans.push_back({it.first, it.second});
sort(ans.begin(), ans.end(), [](const type3& a, const type3& b){
if(a.num != b.num)
return a.num > b.num;
else
return a.site < b.site;
});
if(ans.size() == 0) printf("NA\n");
else{
for(auto it : ans){
printf("%s %d\n", it.site.c_str(), it.num);
}
}
}
}
return 0;
}
第二搏
时间裂开了。。。
欣赏了大神的代码后,发现主要有两点不同:
1,结构体设计:
我的
大神的
显然,更优秀的做法是将id可以拆开的部分拆开,分别存放在不同的变量中,使得寻找对应元素更加快捷(不用反复从字符串中提取),结构更加清晰;
2,能用int型不用string型
从结构体设计中就可以看出,在接收数据时,将字符串相应的部分转换为数字进行存储;
数字之间对比 相较于 字符串之间对比 效率要高一些;
重新升级代码后,完美通过*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
其实还可以在接受数据的同时对部分数据进行分类并且存储,用空间换时间,这样随着查询次数的增加,时间效果会更好。