PAT甲级备考——排序、map映射
题目
PAT (Advanced Level) Practice
排序:
1012、1016、1025、1028、1055、1062、1075、1080、1083、1113、1125、1141
【1137】STL,map映射,排序
【1141】排序、map
【1139】排序、map、遍历set、字符串长度判断是否含有正负号
【1153】排序、printf字符串s.c_str(),cout\map容易超时,换成printf\unordered_map,遍历map for(it:m)
【1125】排序(😀)
【1113】排序(😀)
【1137】STL,map映射,排序
【1137】 Final Grading (25 分)
合并学生的成绩信息,计算最终得分,判断是否合格,并按照一定顺序输出
注意:
(1) sort排序
#include
vector node_lst;
sort(node_lst.begin(), node_lst.end(), cmp);
bool cmp( node n1, node n2){
return n1>n2; 降序
}
注意sort函数、cmp函数中输入的格式是数据结构(node),不是指针(node*)!!会报错!!!
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include <set>
using namespace std;
struct student{
string ID;
int Gp=-1, Gmid=-1, Gfinal=-1, G=-1;
bool qualified = false;
};
int P, M, N;
map<string, int> student_map; // 映射学生id和学生再student_lst对应的index,student_id:index
vector<student*> student_lst; // 保存学生的数据(指针形式)
vector<student> qualified_student_lst;
bool cmp1(student a, student b){ // 注意这里的输入值不是指针,是student数据结构
return a.G != b.G ? a.G>b.G : a.ID<b.ID;
}
int main(){
// 输入学生的成绩信息,保留在student_lst中,其中均为指针形式
cin>>P>>M>>N;
string student_id;
int point, mid_score, final_score, stu_index = 0;
while(P--){
cin>>student_id>>point;
student* stu = new student();
stu->ID = student_id;
stu->Gp = point;
student_map[student_id] = stu_index++;
student_lst.push_back(stu);
}
while(M--){
cin>>student_id>>mid_score;
if (student_map.find(student_id) != student_map.end()){
int index = student_map[student_id];
student_lst[index]->Gmid = mid_score;
}
}
while(N--){
cin>>student_id>>final_score;
if (student_map.find(student_id) != student_map.end()){
int index = student_map[student_id];
student_lst[index]->Gfinal = final_score;
}
}
// 计算学生的最终成绩,并判断是否qualified,并保存至qualified_student_lst
for(int i=0; i<student_lst.size(); i++){
student* temp = student_lst[i];
if(temp->Gfinal < temp->Gmid){
temp->G = int(0.4*temp->Gmid + 0.6*temp->Gfinal + 0.5); //四舍五入
}else{
temp->G = temp->Gfinal;
}
if(temp->Gp>=200 && temp->G>=60){
temp->qualified = true;
qualified_student_lst.push_back(*temp);
}
}
// qualified_student_lst 排序
sort(qualified_student_lst.begin(), qualified_student_lst.end(), cmp1);
// 按照格式形式输出
for(int i=0; i<qualified_student_lst.size(); i++){
student temp = qualified_student_lst[i];
cout<<temp.ID<<" "<<temp.Gp<<" "<<temp.Gmid<<" "<<temp.Gfinal<<" "<<temp.G<<endl;
}
return 0;
}
【1141】排序,map,STL
题⽬⼤意:给出每个学⽣的id、分数、学校,学校名称不区分⼤⼩写,输出学校排名、学校名称、总
加权成绩、学校参赛⼈数。学校名称输出时候以⼩写⽅式输出。
注意:
可以先根据学校将学生信息存入stu_number和stu_score映射中;
接着遍历以上映射,生成数据结构为answer的答案数组ans
原始数据数组data没什么用,可以删掉
遍历map,存入动态数组:
vector ans;
for(auto it=stu_number.begin(); it!=stu_number.end(); it++){
ans.push_back(answer{it->first, (int)stu_score[it->first], stu_number[it->first]});
}
#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std;
struct student{
string ID, school;
int score;
}data[100005];
struct answer{
string school;
int tws, ns;
};
unordered_map<string,int> stu_number;
unordered_map<string,double> stu_score;
bool cmp(answer a, answer b){
if(a.tws != b.tws){
return a.tws > b.tws;
}else if(a.ns != b.ns){
return a.ns < b.ns;
}else{
return a.school < b.school;
}
}
int main(){
// 输入,将学校对应的学生人数存入stu_number,学生对应的分数总和存入stu_score
int N;
cin>>N;
string school;
for(int i=0; i<N; i++){
cin>>data[i].ID;
double score;
scanf("%lf", &score);
if(data[i].ID[0] == 'T')
score = score * 1.5;
else if(data[i].ID[0] == 'B')
score = score / 1.5;
data[i].score = score;
cin>>school;
transform(school.begin(), school.end(), school.begin(), ::tolower);
data[i].school = school;
stu_number[school]++;
stu_score[school] += score;
}
// 将stu_number, stu_score,以及学生的id,存入answer数据结构中,生成答案数组ans
vector<answer> ans;
for(auto it=stu_number.begin(); it!=stu_number.end(); it++){
ans.push_back(answer{it->first, (int)stu_score[it->first], stu_number[it->first]});
}
// ans排序
sort(ans.begin(), ans.end(), cmp);
// 输出,若tws相同则名次并列
printf("%d\n", (int)ans.size());
int rank = 1;
for(int i=0; i<ans.size(); i++){
if(i>0) rank = (ans[i].tws==ans[i-1].tws) ? rank:(i+1);
printf("%d ", rank);
cout<<ans[i].school;
printf(" %d %d\n", ans[i].tws, ans[i].ns);
}
return 0;
}
【1139】排序、map、遍历set、字符串长度判断是否含有正负号
1139 First Contact (30 分)
由于要判断是否是同性别的朋友,由于男女之间相差负号,因此当输入为字符串类型时候,两者的长度不同,因此可以通过这个方式判断是否是同性别(测试点2、3)
#include<iostream>
#include<vector>
#include <string>
#include<unordered_map>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
struct answer{
int f1, f2;
};
map<int,set<int>> friends;// 定义某个人和他的朋友圈
unordered_map<int, bool> arr; // 将a和b的id连起来,bool判断两者是否有关联
bool cmp(answer a, answer b){
return (a.f1!=b.f1)? a.f1<b.f1 : a.f2<b.f2;
}
int main(){
// 输入
int N, M, a, b, K;
scanf("%d %d", &N, &M);
vector<int> v[10000];
for(int i=0; i<M; i++){
string a, b;
cin >> a >> b;
if (a.length() == b.length()) { // 判断a和b是否是同性别的好友
friends[abs(stoi(a))].insert(abs(stoi(b))); // a的朋友set中插入b,b的朋友set中国插入a
friends[abs(stoi(b))].insert(abs(stoi(a)));
}
arr[abs(stoi(a)) * 10000 + abs(stoi(b))] = arr[abs(stoi(b)) * 10000 + abs(stoi(a))] = true; // 表示a和b之间存在关联
}
// 判断
scanf("%d", &K);
int x, y;
while(K--){
// 找到x的与y的朋友是朋友的朋友
scanf("%d %d", &x, &y);
vector<answer> ans;
x = abs(x);
y = abs(y);
for(auto it1=friends[x].begin(); it1!=friends[x].end(); it1++){ // 遍历x的朋友圈
for(auto it2=friends[y].begin(); it2!=friends[y].end(); it2++){ // 遍历y的朋友圈
if((*it1==y) || (*it2==x)) continue; // 如果x的朋友是y,或者y的朋友是x则继续
if (arr[abs(*it1) * 10000 + abs(*it2)] == true){ // 如果x的朋友和y的朋友有关联,则把两个放入ans列表中
ans.push_back({abs(*it1), abs(*it2)});
}
}
}
// 排序并输出
sort(ans.begin(), ans.end(), cmp);
printf("%d\n",int(ans.size()));
for(int i=0; i<ans.size(); i++){
printf("%04d %04d\n", ans[i].f1, ans[i].f2);
}
}
}
【1153】排序、printf字符串s.c_str(),cout\map容易超时,换乘printf\unordered_map,遍历map for(it:m)
注意:
(1)若map运行超时,可换为unordered_map;
(2)若cout运行超时,可换为printf
(3)可以在读入数据时不先生成结果map
(4)printf(“%s”, s.c_str()),打印字符串
(5)遍历map:
for(auto it:m )
ans1.push_back(node{it.first, it.second});
#include<iostream>
#include<unordered_map>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
string id;
int score;
};
bool cmp(node a, node b){
return (a.score!=b.score)?a.score>b.score: a.id<b.id;
}
int main(){
int n, m, judge;
cin>>n>>m;
vector<node> stu(n);
// 输入学生id和分数score
for(int i=0; i<n; i++)
cin>>stu[i].id>>stu[i].score;
// 分情况讨论
for(int i=0; i<m; i++){
vector<node> ans1;
string s;
cin>>judge>>s;
printf("Case %d: %d %s\n", i+1, judge, s.c_str());
int num=0, total=0;
if(judge == 1){
char l = s[0];
for(int j=0; j<n; j++)
if(stu[j].id[0]==l) ans1.push_back(stu[j]);
sort(ans1.begin(), ans1.end(), cmp);
}
else if(judge == 2){
string site_number = s;
for(int j=0; j<n; j++){
if(stu[j].id.substr(1,3) == site_number){
num++;
total += stu[j].score;
}
}
if(num!=0) cout<<num<<" "<<total<<endl;
}else if(judge == 3){
string temp_date = s;
unordered_map<string, int> m;
for(int j=0; j<n; j++){
if(stu[j].id.substr(4,6) == temp_date)
m[stu[j].id.substr(1,3)]++;
}
for(auto it:m )
ans1.push_back(node{it.first, it.second});
sort(ans1.begin(), ans1.end(), cmp);
}
for(int j=0; j<ans1.size(); j++)
printf("%s %d\n", ans1[j].id.c_str(), ans1[j].score);
if (((judge == 1 || judge == 3) && ans1.size() == 0) || (judge == 2 && num ==0)) printf("NA\n");
}
}