牛客网编程题——成绩排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/N1neDing/article/details/82805017

题目描述

用一维数组存储学号和成绩,然后,按成绩排序输出。

输入:输入第一行包括一个整数N(1<=N<=100),代表学生的个数。 接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。

输出:按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。 如果学生的成绩相同,则按照学号的大小进行从小到大排序。

解题思路1:

如果只对一个项进行排序且项无重复(如果key重复,后面插入的相同key会插入不成功),可以使用map直接插入,map自身会对key进行排序,插入完成之后可以直接输出,便是从小到大有序序列,但是本题显然不适用,不过也不妨为一种思路。

解题思路2:

使用一个结构体将各种数据纳入其中,然后使用自定义的sort函数对之排序。

参考源码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Score
{
        int id; 
        int score;
};
bool cmp(Score s1,Score s2) 
{
        if(s1.score != s2.score) return s1.score < s2.score;
        return s1.id < s2.id;
}
int main()
{
        vector<Score> student;
        int num;
        cin>>num;
        int id,score;
        while(num--)
        {   
                cin>>id>>score;
                Score temp;
                temp.id = id; 
                temp.score = score;
                student.push_back(temp);
        }   
        sort(student.begin(),student.end(),cmp);
        for(int i = 0;i < student.size();i++)
        {   
                cout<<student[i].id<<" "<<student[i].score<<endl;
        }   
        return 0;
}  

类似题目1:

题目描述:

月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需 求量,请你计算可以获得的最大收益是多少。

注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18、15、10万吨,总售价分别为75、 72、45亿元。如果市场的最大需求量只有20万吨,那么我们最大收益策略应该是卖出全部15万吨第2种月饼、以及5万吨第3种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入:每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数、以及不超过500(以万吨为单位)的正整数 D表示市场最大需求量。随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价(以亿 元为单位)。数字间以空格分隔。

输出:对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后2位

解题思路:

同样的方法,使用自定义sort函数,需要注意的是,输出为小数点后两位时,有两种写法:1.printf("%.2f",money) 2.cout<<fixed<<setprecision(2)<<money<<endl;fixed表示末尾填充0,需要添加头文件<iomanip>

参考源码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
struct CakeInfo
{
        double count;
        double price;
        double single;
};
bool cmp(CakeInfo cake1,CakeInfo cake2)
{
        return cake1.single > cake2.single;
}
int main()
{
        int num;
        double need;
        cin>>num;
        cin>>need;
        vector<CakeInfo> mooncake(num);
        for(int i = 0;i < num;i++)
        {
                double cnt;
                cin>>cnt;
                mooncake[i].count = cnt;
        }
        for(int i = 0;i < num;i++)
        {
                double price;
                cin>>price;
                mooncake[i].price = price;
        }
        for(int i = 0;i < num;i++)
        {
                mooncake[i].single = mooncake[i].price / mooncake[i].count;
        }
        sort(mooncake.begin(),mooncake.end(),cmp);
        double money = 0;
        double count_need = need;
        for(int i = 0;i < num;i++)
        {
                if(mooncake[i].count < count_need)
                {
                        money += mooncake[i].price;
                        count_need -= mooncake[i].count;
                }
                else if(mooncake[i].count >= count_need)
                {
                        money += mooncake[i].single * count_need;
                        break;
                }
        }
        //printf("%.2f\n",money);
        cout<<fixed<<setprecision(2)<<money<<endl;
        return 0;
}

类似题目2:

题目描述:

有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息。

输入:测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。 每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整形数)、成绩(小于等于100的正数)。

输出:将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。 然后输出学生信息,按照如下格式: 姓名 年龄 成绩

学生姓名的字母序区分字母的大小写,如A要比a的字母序靠前(因为A的ASC码比a的ASC码要小)。

参考源码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct Score
{
        string name;
        int age; 
        double score;
};
bool cmp(Score s1,Score s2) 
{
        if(s1.score != s2.score) return s1.score < s2.score;
        if(s1.name != s2.name) return s1.name < s2.name;
        return s1.age < s2.age;
}
int main()
{
        int num;
        cin>>num;
        vector<Score> student(num);
        string name;
        int age;
        double score;
        for(int i = 0;i < num;i++)
        {
                cin>>student[i].name;
                cin>>student[i].age;
                cin>>student[i].score;
        }
        sort(student.begin(),student.end(),cmp);
        for(int i = 0;i < student.size();i++)
        {
                cout<<student[i].name<<" "<<student[i].age<<" "<<student[i].score<<endl;
        }
        return 0;
}  

类似题目3:

题目描述:

输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩都按先录入排列在前的规则处理。

示例:

jack      70

peter     96
Tom       70
smith     67

从高到低  成绩
peter     96
jack      70
Tom       70
smith     67

从低到高

smith     67

jack      70
Tom      70
peter     96

输入:输入多行,先输入要排序的人的个数,然后输入排序方法0(降序)或者1(升序)再分别输入他们的名字和成绩,以一个空格隔开

输出:按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开

解题思路1:

sort本身实现原理较复杂,当数据量大时,使用快排,同时还有插入排序,是不稳定的,因为要求先录入的放前面,所以此处应当使用stable_sort,为稳定排序。

参考源码1:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct Score
{
        string name; 
        int score;
};
bool cmp1(Score s1,Score s2) 
{
        return s1.score < s2.score;
}
bool cmp2(Score s1,Score s2) 
{
        return s1.score > s2.score;
}
int main()
{
        vector<Score> student;
        int num;
        int key;
        while(cin>>num)
        {
                cin>>key;
                while(num--)
                {
                        string name;
                        int score;
                        cin>>name;
                        cin>>score;
                        Score temp;
                        temp.name = name;
                        temp.score = score;
                        student.push_back(temp);
                }
                if(key == 1)
                {
                        stable_sort(student.begin(),student.end(),cmp1);
                }
                if(key == 0)
                {
                        stable_sort(student.begin(),student.end(),cmp2);
                }
                for(int i = 0;i < student.size();i++)
                {
                        cout<<student[i].name<<" "<<student[i].score<<endl;
                }
                student.clear();
        }
        return 0;
}  

解题思路2:

构建0-100个vector,代表每个分数共有多少个姓名,每个vector内构建一个string数组,根据对应的分数将姓名插入到对应的序列中,然后顺序输出。

参考源码2:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
        int num;
        while(cin>>num)
        {
                vector<vector<string>> student(101);
                int key;
                cin>>key;
                for(int i = 0;i < num;i++)
                {
                        string str;
                        int score;
                        cin>>str;
                        cin>>score;
                        student[score].push_back(str);
                }
                if(key == 1)
                {
                        for(int i = 0;i <= 100;i++)
                        {
                                if(student[i].size() != 0)
                                {
                                        for(int j = 0;j < student[i].size();j++)
                                        {
                                                cout<<student[i][j]<<" "<<i<<endl;
                                        }
                                }
                        }
                }
                if(key == 0)
                {
                        for(int i = 100;i >= 0;i--)
                        {
                                if(student[i].size() != 0)
                                {
                                        for(int j = 0;j < student[i].size();j++)
                                        {
                                                cout<<student[i][j]<<" "<<i<<endl;
                                        }
                                }
                        }
                }
        }
        return 0;
}

猜你喜欢

转载自blog.csdn.net/N1neDing/article/details/82805017