头歌 | 数据结构与算法课程设计-算法与竞赛(第2章) - C++与算法基础一

Algorithm中文意思是算法,是一个计算的具体步骤,常用于数据处理、计算以及自动推理。它作为C++标准模版库STL中最重要的头文件之一,其提供了大量非成员模版函数,例如排序操作、二分查找操作、集合操作以及堆操作等。同时可以通过迭代器或指针访问的任何对象序列,例如STL容器数组或实例。

本实训主要设置了三个关卡:第一关介绍了Algorithm中的Min/Max操作;第二关是自定义数据类型结构体下的Min函数应用;第三关讲的是C++模板中的快速排序算法。最后在每个关卡都设置了实例,考察学员对所讲内容的理解和在线编程能力。

 

第1关:Algorithm模板中的Min/Max应用

任务描述

本关任务:基于Algorithm中的模板函数Min/Max编写一个程序:在整型、浮点型、字符类型、字符串类型中,计算出两个相同类型数据间的最小值和最大值。

相关知识

为了完成本关任务,你需要掌握:1.Algorithm模板函数min,2.Algorithm模板函数max,3.Algorithm模板函数minmax

Algorithm 模板函数 min

Algorithm模板函数中,关于min的用法主要有两个:基础数据类型的最小值函数和自定义数据类型的最小值函数。基础数据类型指整型int,单精度浮点型float,双精度浮点型double,字符类型char,字符串指针类型char*,字符串对象类型string等数据类型,而自定义的数据类型通常为结构体数据类型。其函数原型如下:

1 default (1): // 默认的基础数据类型最小值函数
2     template <class T> const T& min (const T& a, const T& b);
3 custom (2): // 自定义的数据类型最小值函数
4     template <class T, class Compare>
5     const T& min (const T& a, const T& b, Compare comp);

在本关卡中,主要是介绍默认的基础类型最小值函数及其实战,有关自定义数据类型的最小值函数的详细介绍和实战将在下一个关卡给出。使用示例如下:

1 #include <algorithm>        // algorithm头文件
2 int a=1, b=2;
3 int c = std::min(a, b);        // 调用min函数方式一
4 using namespace std;        // or 调用min函数方式二
5 int d = min(a, b);

Algorithm 模板函数 max

最大值函数与最小值函数类似,使用方法也是一样的,也包含两个主要的用法。其函数原型如下:

1 default (1):
2     template <class T> const T& max (const T& a, const T& b);
3 custom (2):
4     template <class T, class Compare>
5     const T& max (const T& a, const T& b, Compare comp);

Algorithm 模板函数 minmax

特别的,在Algorithm模板函数中还包含一个特殊的函数:最小值最大值函数,它以数据对pair的形式返回两个值:最小值和最大值。同样的,该函数也能处理基础数据类型和自定义数据类型,其函数原型如下:

1 default (1):
2     template <class T>
3     pair <const T&,const T&> minmax (const T& a, const T& b);
4 custom (2):
5     template <class T, class Compare>
6     pair <const T&,const T&> minmax (const T& a, const T& b, Compare comp);

因为 minmax 的返回值的使用方式比较特殊,通过 .first 和 .second 来分别获取最小值和最大值,一个示例如下:

 1 // minmax example
 2 #include <iostream>     // std::cout
 3 #include <algorithm>    // std::minmax
 4 int main () {
 5     auto result = std::minmax({1,2,3,4,5});
 6     std::cout << "minmax({1,2,3,4,5}): ";
 7     std::cout << result.first << ' ' << result.second << '\n';
 8     int a = 1, b = 2;
 9     auto result2 = std::minmax(a, b);
10     std::cout << "minmax({1,2}): ";
11     std::cout << result2.first << ' ' << result2.second << '\n';
12     return 0;
13 }
14 /* 输出结果:
15 minmax({1,2,3,4,5}): 1 5
16 minmax({1,2}): 1 2
17 */

编程要求

本关的编程任务是补全右侧代码片段mainBeginEnd中间的代码,具体要求如下:

  • main中,首先按照整型、浮点型、字符类型、字符串类型依次读取数据,然后调用minmax操作(或者minmax操作)计算出最小值和最大值,最后按照示例的格式严格输出最小值和最大值结果。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 53 86

0.04 0.41

g y

ertg erty

预期输出:

min(53,86)==53

max(53,86)==86

min(0.04,0.41)==0.04

max(0.04,0.41)==0.41

min(g,y)==g

max(g,y)==y

min(ertg,erty)==ertg

max(ertg,erty)==erty

 

输入格式: 第一行:两个整型类型数据

第二行:两个浮点类型数据

第三行:两个字符类型数据

第四行:两个字符串类型数据

 

输出格式: 最后一行末尾有换行符\n!!!

请严格参照上述示例预期输出的格式!!!


开始你的任务吧,祝你成功!

 

 1 //
 2 //  main.cpp
 3 //  step1
 4 //
 5 //  Created by ljpc on 2018/7/2.
 6 //  Copyright © 2018年 ljpc. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <algorithm>
11 #include <string>
12 #include <cstdio>
13 using namespace std;
14 
15 int main(int argc, const char * argv[]) {
16     
17 
18     // 请在这里补充代码,完成本关任务
19     /********** Begin *********/
20     int a,b;
21     float c,d;
22     char e,f;
23     string g,h;
24     cin>>a>>b>>c>>d>>e>>f>>g>>h;
25     cout<<"min("<<a<<","<<b<<")=="<<min(a,b)<<endl;
26     cout<<"max("<<a<<","<<b<<")=="<<max(a,b)<<endl;
27     cout<<"min("<<c<<","<<d<<")=="<<min(c,d)<<endl;
28     cout<<"max("<<c<<","<<d<<")=="<<max(c,d)<<endl;
29     cout<<"min("<<e<<","<<f<<")=="<<min(e,f)<<endl;    
30     cout<<"max("<<e<<","<<f<<")=="<<max(e,f)<<endl;    
31     cout<<"min("<<g<<","<<h<<")=="<<min(g,h)<<endl;        
32     cout<<"max("<<g<<","<<h<<")=="<<max(g,h)<<endl;        
33     /********** End **********/
34     
35     return 0;
36 }
点击查看代码

 

 

第2关:min函数在自定义数据类型下的应用

任务描述

本关任务:编写一个程序,基于结构体存储学生信息,包含学号,姓名和学科成绩,并使用模板函数min获取学科成绩较低的学生信息,如果成绩相同,则获取学号靠前的学生信息。

相关知识

为了完成本关任务,你需要掌握:1.自定义数据类型的模板函数min

自定义数据类型的模板函数min

自定义数据类型的的学生信息结构体至少包含三项数据类型:

  1. 整型类型:学号;
  2. 字符串类型:姓名;
  3. 整型类型:学科成绩:
1 struct Student{
2     int numberID;
3     char name[20];
4     int score;
5 };

模板函数min在处理自定义数据类型的时候,需要依据该数据类型的比较规则定义一个比较函数,该比较函数返回比较的真值。比如两个整数 和 

1 bool comp(int a, int b){ return a<b;}
2 int c = min(a, b, comp);

在本关卡中,首先比较学生的成绩:若成绩不同,则返回成绩低的;若成绩相同,返回学号靠前的(即数值小的)。模板函数 min 处理自定义数据类型的函数原型如下:

1 template <class T, class Compare>
2 bool comp(const T& a, const T& b);// 按定义的比较规则返回a<b的真值
3 const T& min (const T& a, const T& b, Compare comp);

编程要求

本关的编程任务是补全右侧代码片段 min_cmp 和 main 中 Begin 至 End 中间的代码,具体要求如下:

  • 在 min_cmp 中,完成两个学生信息的比较,首先比较学生的成绩:若成绩不同,则返回成绩比较的真值;若成绩相同,返回学号比较的真值。
  • 在 main 中,使用结构体读取和记录学生信息,并基于模板函数 min 实现学生信息的比较,获取较小成绩的学生信息并输出。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 

20180108 Henry 54

20180126 Charles 72

预期输出:

20180108 Henry 54

 

测试输入:

20180122 Niki 71

20180110 Barbara 71

预期输出:

20180110 Barbara 71

 

输入格式:两行,每行一个学生信息:学号 姓名 成绩

输出格式:一行,输出学生信息,末尾换行\n


开始你的任务吧,祝你成功!

 

 1 //
 2 //  main.cpp
 3 //  step2
 4 //
 5 //  Created by ljpc on 2018/7/6.
 6 //  Copyright © 2018年 ljpc. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <algorithm>
11 #include <cstdio>
12 #include <cstring>
13 #include <string>
14 
15 using namespace std;
16 
17 struct Student{
18     int numberID;
19     char name[20];
20     int score;
21     Student(){}
22     Student(int id_, char *name_, int score_){
23         numberID = id_;
24         strcpy(name, name_);
25         score = score_;
26     }
27     void in()
28     {
29         scanf("%d %s %d", &numberID, name, &score);
30     }
31     void out()
32     {
33         printf("%d %s %d\n", numberID, name, score);
34     }
35 };
36 
37 bool min_cmp(Student S1, Student S2){
38     // 请在这里补充代码,完成本关任务
39     /********** Begin *********/
40     if (S1.score!=S2.score) return S1.score<S2.score;
41     else return S1.numberID<S2.numberID;
42 
43     /********** End **********/
44 }
45 
46 int main(int argc, const char * argv[]) 
47 {    
48     
49     // 请在这里补充代码,完成本关任务
50     /********** Begin *********/
51     Student stu1,stu2;
52     stu1.in();
53     stu2.in();
54     Student stu;
55     stu=min(stu1,stu2,min_cmp);
56     stu.out();
57  
58     /********** End **********/
59 
60     return 0;
61 }
点击查看代码

 

 

第3关:使用模板函数sort对学生成绩进行排序

任务描述

本关任务:编写一个程序,基于结构体存储N个学生信息,包含学号,姓名和学科成绩,并使用模板函数sort完成对学生信息的排序:成绩高的排序靠前,若成绩相同,则学号小的排序靠前。

相关知识

为了完成本关任务,你需要掌握:1.自定义数据类型下的排序模板函数sort

自定义数据类型下的排序模板函数sort

Algorithm中的排序函数是基于快速排序算法实现的,复杂度为O(N*logN)。快速排序算法在1962年由C. A. R. Hoare提出,其基本思想是:通过一趟排序将待排序的数据分割成独立的两部分,左边部分的所有数据比右边部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,最后达到整个数据变成有序序列。

模板函数sort具有两种模式,一种是数据之间已有排序规则,比如整型数据、浮点数据,它们的大小比较是确定的;另一种是数据之间没有现成的排序规则,需要自定义排序规则,这类适用于自定义数据类型。它们函数原型如下:

1 default (1):
2     template <class RandomAccessIterator>
3     void sort (RandomAccessIterator first, RandomAccessIterator last);
4 custom (2):
5     template <class RandomAccessIterator, class Compare>
6     void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

本关卡是对存储有N个学生信息的结构体数组进行排序,一般有两种方式:

  • 在结构体中重载小于比较符<,因为sort函数默认使用<比较符,只要返回this.score>S.score的比较真值,那么使用sort排序将得到成绩从高到低的排序结果。由此,最后直接调用sort函数对结构体数组进行排序即可:
 1 struct Student{
 2   int numberID;
 3   char name[20];
 4   int score;
 5   bool operator < (const Student &S)const{ 
 6   //完成结构体比较规则:Student this VS. Student S
 7   //先比较成绩,若成绩相同,则比较学号
 8   }
 9 }
10 Student student[10];
11 sort(student, student+10);
  • 实现一个结构体比较函数,然后作为参数传入sort函数完成排序中的结构体间的大小比较:
1 bool max_cmp(Student S1, Student S2){
2 //完成结构体比较规则:Student S1 VS. Student S2
3 //先比较成绩,若成绩相同,则比较学号
4 }
5 Student student[10];
6 sort(student, student+10, max_cmp);

编程要求

本关的编程任务是补全右侧代码片段 operator max_cmp 和 main 中 Begin 至 End 中间的代码,具体要求如下:

  • 在 operator < 中,按照先进行学生成绩的比较,若成绩相等,再比较学号的比较规则,完成结构体 this 和结构体 的大小比较,并返回比较真值。
  • 在 max_cmp 中,按照以上规则完成结构体 S1 和结构体 S2 的大小比较,并返回比较真值。
  • 在 main 中,基于自定义的结构体数据类型读取和存储学生信息,然后使用 sort 函数完成学生成绩的从大到小排序,最后输出排序后的学生信息。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入: 

7

20180127 Helen 88

20180111 Martin 51

20180102 James 88

20180114 Joseph 60

20180106 Joan 99

20180120 Lily 91

20180105 Malcolm 88

预期输出:

20180106 Joan 99

20180120 Lily 91

20180102 James 88

20180105 Malcolm 88

20180127 Helen 88

20180114 Joseph 60

20180111 Martin 51

 

输入格式:第一行学生数N,余下 行学生信息

输出格式: 行排序后的学生信息,每行学生信息中间空格隔开,末尾换行。


开始你的任务吧,祝你成功!

 

 1 //
 2 //  main.cpp
 3 //  step3
 4 //
 5 //  Created by ljpc on 2018/7/6.
 6 //  Copyright ? 2018年 ljpc. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <algorithm>
11 #include <cstdio>
12 #include <cstring>
13 #include <string>
14 
15 using namespace std;
16 
17 struct Student {
18     int numberID;
19     char name[20];
20     int score;
21     Student() {}
22     Student(int id_, char *name_, int score_) {
23         numberID = id_;
24         strcpy(name, name_);
25         score = score_;
26     }
27     void in() {
28         scanf("%d %s %d", &numberID, name, &score);
29     }
30     void out() {
31         printf("%d %s %d\n", numberID, name, score);
32     }
33     bool operator < (const Student &S)const {//定义sort排序规则,与第2关相同
34         // 请在这里补充代码,完成本关任务
35         /********** Begin *********/
36         if(score == S.score) return numberID < S.numberID;
37         else return score > S.score;
38         /********** End **********/
39     }
40 };
41 bool max_cmp(Student S1, Student S2) {//定义sort排序规则
42     // 请在这里补充代码,完成本关任务
43     /********** Begin *********/
44     if(S1.score ==S2.score) return S1.numberID > S1.numberID;//和第2关一样的算法
45     else return S1.score > S2.score;
46     /********** End **********/
47 }
48 
49 int main(int argc, const char * argv[]) {
50     // 请在这里补充代码,完成本关任务
51     /********** Begin *********/
52     int a;
53     cin>>a;
54     Student student[a+10];//利用结构体定义一个结构体数组,用于存放学生的数据
55     for(int i=0; i<=a; i++) {//不断循环获取学生数据
56         cin>>student[i].numberID>>student[i].name>>student[i].score;
57     }
58     sort(student,student+a);//利用sort函数进行排序
59     for(int i=0; i<a; i++) {//不断循环输出每一个学生的数据
60         cout<<student[i].numberID<<" "<<student[i].name<<" "<<student[i].score<<endl;
61     }
62     /********** End **********/
63 
64     return 0;
65 }
点击查看代码

 

posted @ 2021-09-28 23:07  ◆◇dear丶妖孽╮ゞ  阅读(3482)  评论(0编辑  收藏  举报
……
芋、头、sleepwalking、…