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");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值