1025. PAT Ranking (25)

来源:互联网 发布:cecs钢结构绘图软件 编辑:程序博客网 时间:2024/06/06 12:42

本题要求将获得地区考生进行本地排名和总排名

题目完成思路:
保存考生的地区、分数、编号信息,并对其进行排序最后输出;
一开始考虑得到考生信息的输入后直接开始答案的输出,但是这个做法相对而言比较复杂,可能会导致题目完成速度的不够,因此最后选用先以不同的方式排序,并记录两个排名,最后输出的方式。

#include<iostream>#include<vector>#include<algorithm>#include<string>using namespace std;class student{public:    string ID;    int score;    int locate;    int Rank;    int localRank;    student(const string&_ID,int _score,int _locate){        ID = _ID;        score = _score;        locate = _locate;    }    void print(){     cout << ID << ' ' << Rank << ' ' << locate << ' ' << localRank << endl;    }};vector<student> students;int TotalArea;bool compare1(const student&a,const student&b){    if(a.score > b.score)return true;    else if(a.score < b.score)return false;    else if(a.ID < b.ID)return true;    else return false;}bool compare2(const student&a,const student&b){    if(a.locate < b.locate)return true;    else if(a.locate > b.locate)return false;    else return compare1(a,b);}int main(void){    cin >> TotalArea;    int i,j,k;    string buf;    int score;    for(i = 0;i < TotalArea;i++){        cin >>j;//本地人数        for(k = 0;k < j;k++){            cin >> buf >> score;            students.push_back(student(buf,score,i + 1));        }//每人    }//每地区    //设定分区排名    sort(students.begin(),students.end(),compare2);    int area = 1;    j = k = 1;    score = students[0].score;    for(auto i = students.begin();i < students.end();i++,k++){        if(area!=i->locate){            j = k = 1;            score = i->score;            area = i->locate;        }        else if(score != i->score){            j = k;            score = i->score;        }        i->localRank = j;    }    //设定总排名    sort(students.begin(),students.end(),compare1);    j = k = 1;    score = students[0].score;    for(auto i = students.begin();i < students.end();i++,k++){        if(score != i->score){            j = k;            score = i->score;        }        i->Rank = j;    }    cout << students.size() << endl;    for(auto i = students.begin();i < students.end();i++)i->print();    return 0;}

完成后的反思:
上述中,可以见到在compare函数和获得两个排名的部分有大量的重复代码。如果想要去掉两个重复代码的话,可以先把不同区域的人放到不同容器里,分别获得容器内的排名,再放到同一个容器内获得总排名,考虑到合并容器的速度,可以选用list链表来方便的实现,改进代码如下:

#include<iostream>#include<vector>#include<algorithm>#include<list>#include<string>using namespace std;class student{public:    string ID;    int score;    int locate;    int Rank;    int localRank;    student(const string&_ID,int _score,int _locate){        ID = _ID;        score = _score;        locate = _locate;    }    void print(){cout << ID << ' ' << Rank << ' ' << locate << ' ' << localRank << endl;}    bool operator<(const student&b){        if(score > b.score)return true;        else if(score < b.score)return false;        else if(ID < b.ID)return true;        else return false;    }};typedef list<student>Area;vector<Area> students;int TotalArea;void getrank(Area& stu){    //设定总排名    stu.sort();    int j = 1,k = 1,score = stu.front().score;    for(auto i = stu.begin();i != stu.end();i++,k++){        if(score != i->score){            j = k;            score = i->score;        }        //这个语句只是为了通用获得两个排名而已        i->localRank = i->Rank;        i->Rank = j;    }}int main(void){    cin >> TotalArea;    int i,j,k;    string buf;    int score;    for(i = 0;i < TotalArea;i++){        cin >>j;//本地人数        students.push_back(Area());        for(k = 0;k < j;k++){            cin >> buf >> score;            students[i].push_back(student(buf,score,i + 1));        }//每人    }//每地区    for(i = 0;i < TotalArea;i++)getrank(students[i]);    for(i = 1;i < TotalArea;i++)students[0].merge(students[i]);    getrank(students[0]);    cout << students[0].size() << endl;    for(auto i = students[0].begin();i != students[0].end();i++)i->print();    return 0;}
0 0