蓝桥备赛(七)- 函数与递归(中)
一、函数重载
1.1 重载概念
引入:
比如:如果我们现在想要写一个函数 , 求两个整数的和 :
#include <cstdio>
#include <iostream>
using namespace std;
int IntAdd(int x, int y)
{
return x + y;
}
int main()
{
int a, b;
cin >> a >> b;
int r = IntAdd(a, b);
cout << r << endl;
return 0;
}
如果我们还想实现两个浮点数的和呢?
#include <cstdio>
#include <iostream>
using namespace std;
int IntAdd(int x, int y)
{
return x + y;
}
float FloatAdd(float x, float y)
{
return x + y;
}
int main()
{
int a, b;
cin >> a >> b;
int r = IntAdd(a, b);
cout << r << endl;
float c, d;
cin >> c >> d;
float f = FloatAdd(c, d);
cout << f << endl;
return 0;
}
那 .. 还有double , 还有....
我们发现 , 这些都是功能相似 , 只是类型不同 ; C++ 引入了函数重载的功能 ,对于这种情况 , 可以只使用一个函数名 来实现不同类型的变量相加 , 大大减少了我们的记忆成本和代码的冗余。
函数重载 : C++ 中的函数重载是指在 同一个作用域中可以有多个同名函数 , 它们的函数名称相同 , 但是参数列表不同 。
函数返回类型 函数名(参数1 , 参数 2 , .... )
1 ) 不同 : 参数的数量 , 类型和顺序至少有一个不同 ;
2 )函数的返回类型并不影响函数的重载 , 因为C++编译器 不会 根据返回类型来区分不同函数。
1.2 重载举例
#include <cstdio>
#include <iostream>
using namespace std;
//1.参数类型不同
int Add(int x, int y)
{
return x + y;
}
float Add(float x, float y)
{
return x + y;
}
//2.参数数量不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
//3.参数顺序不同
void f(int a, char b)
{
cout << "f(int a, char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
int main()
{
Add(10, 20);
Add(1.1f , 2.2f);
f();
f(10);
f(10, 'a');
f('a',10);
return 0;
}
二、函数练习
练习一:简单算术表达式求值
B2130 简单算术表达式求值 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;
int calc(int x , char y , int z)
{
switch(y)
{
case '+':
return x + z;
case '-':
return x - z;
case '*':
return x * z;
case '/':
return x / z;
case '%':
return x % z;
}
}
int main()
{
int a = 0 , b = 0;
char c = 0;
cin >> a >> c >> b;
int ret = calc(a,c,b);
cout << ret << endl;
return 0;
}
也可以用scanf , 但是%c 前面加个空格 , 表示忽略空白字符 :
#include <iostream>
#include <cstdio>
using namespace std;
int calc(int x , char y , int z)
{
switch(y)
{
case '+':
return x + z;
case '-':
return x - z;
case '*':
return x * z;
case '/':
return x / z;
case '%':
return x % z;
}
}
int main()
{
int a , b ;
char c ;
scanf("%d %c%d",&a , &c , &b);
int ret = calc(a,c,b);
cout << ret << endl;
return 0;
}
碎碎念:说实话 , 如果%c前面不加空格 , 这道题其实也可以过,是因为后台测试组可能只是在题目吓唬吓唬你 , 测试点并没有空格;
练习二:最大数 max(x,y,z)
B2129 最大数 max(x,y,z) - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;
int max(int x , int y , int z)
{
int m = x > y ? x : y;
if(m < z)
m = z;
return m;
}
int main()
{
int a,b,c;
cin >> a >> b >> c;
double ret = max(a,b,c) * 1.0 / (max(a+b,b,c)*max(a,b,b+c));
printf("%.3lf\n",ret);
return 0;
}
拓展学习:库函数max 和 min
1)max
1 . 在 C++ 中, max 函数用于返回两个值中的较大值。它是 C++ 标准库 <algorithm> 头文件中的⼀个函数。2 . max 函数可以用于各种类型 ,包括内置类型(如 int 、 double )以及用户自定义类型(如类或结构体),只要这些类型支持比较操作。#include <algorithm>template <class T>const T& max(const T& a, const T& b); //默认比较template <class T, class Compare>const T& max(const T& a, const T& b, Compare comp); //自定义比较器
参数:
1 . a: 要比较的第⼀个值。2 . b: 要比较的第⼆个值。3 . comp (可选): 自定义比较函数对象或比较函数,用于确定“较大”值的标准。4 . 比较函数应当返回一个布尔值,表示第一个参数是否 “小于” 第⼆个参数。
返回值:
返回 a 和 b 中的较大值 , 如果两个值相等 , 则返回 a
代码举例1:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int a = 10;
int b = 20;
int ret = max(a,b);
cout << ret << endl;
cout << endl;
string s1 = "abcdef";
string s2 = "bbf";
string s = max(s1,s2);
cout << s << endl;
return 0;
}
代码举例2:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp_str(string str1,string str2)
{
return str1.size() < str2.size() ;
}
int main()
{
string s1 = "abcdef";
string s2 = "bbf";
string s = max(s1,s2,cmp_str);
cout << s << endl;
return 0;
}
2)min
C++中 , min函数用于返回两个值中的较小值 。 他和 max函数相似 , 也是在C++库 <algorithm> 头文件中的一个函数 。用法和max 函数一模一样 , 只是实现的效果恰好相反。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp_str(string str1,string str2)
{
return str1.size() < str2.size() ;
}
int main()
{
string s1 = "abcdef";
string s2 = "bbf";
string s = min(s1,s2,cmp_str);
cout << s << endl;
return 0;
}
有了max函数 , 上面判断最大值时 , 我们就可以直接使用max 了 :
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int max(int x , int y , int z)
{
int m = max(x,y);
return max(m,z);
}
int main()
{
int a,b,c;
cin >> a >> b >> c;
double ret = max(a,b,c) * 1.0 / (max(a+b,b,c)*max(a,b,b+c));
printf("%.3lf\n",ret);
return 0;
}
练习三:最高分与最低分之差
登录—专业IT笔试面试备考平台_牛客网
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int _max,_min;
int num = 0;
cin >> num;
//假设第一个数是最大/小值
_max = num;
_min = num;
for(int i = 1;i< n ; i++)
{
cin >> num;
_max = max(_max,num);
_min = min(_min,num);
}
cout << (_max - _min) << endl;
return 0;
}
方法二:可以让_max 初始化为 0 , _min 初始化为100
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int _max = 0;
int _min = 100;
int num = 0;
for(int i = 0;i< n ; i++)
{
cin >> num;
_max = max(_max,num);
_min = min(_min,num);
}
cout << (_max - _min) << endl;
return 0;
}
练习四:歌唱比赛
P5738 【深基7.例4】歌唱比赛 - 洛谷
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n , m;
double ret = 0;
cin >> n >> m;
//处理n名学生的成绩
for(int i = 0;i < n ; i++)
{
//处理一名学生的成绩
int _max = 0;
int _min = 10;
int sum = 0;
for(int j = 0; j < m ; j++)
{
int s;
cin >> s;
sum += s;
_max = max(_max,s);
_min = min(_min,s);
}
double tmp = (sum - _max - _min)*1.0/( m - 2);
ret = max(ret , tmp);
}
printf("%.2lf",ret);
return 0;
}
注意:这里不能使用while 循环 , 如果使用 while(m--) ,m 会减到0 , (sum - _max - _min)*1.0/( m - 2) , 会使 m - 2 = -2 ; 不符合题解!
练习五:求正整数 2 和 n 之间的完全数
B2127 求正整数 2 和 n 之间的完全数 - 洛谷
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool perfert_num(int m)
{
int sum = 0;
for(int i = 1 ; i < m ; i++)
{
if(m % i == 0)
sum += i;
}
return sum == m;
}
int main()
{
int n ;
cin >> n;
//产生2~n的数字
for(int i = 2; i <= n ; i++)
{
//判断 i 是否为完全数
if(perfert_num(i))
{
cout << i << endl;
}
}
return 0;
}
练习六:甲流病人初筛
B2131 甲流病人初筛 - 洛谷
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool check(float wen,int flag)
{
return (wen >= 37.5 && flag == 1);
}
int main()
{
int n;
cin >> n;
string name;
float wen;
int flag;
int sum = 0;
while(n--)
{
cin >> name >> wen >> flag;
//判断是否为甲流病人
if(check(wen,flag))
{
cout << name << endl;
sum++;
}
}
cout << sum << endl;
return 0;
}
练习七:素数个数
B2128 素数个数 - 洛谷
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
bool is_prime(int m)
{
if(m <= 1)
return false;
for(int i = 2; i <= sqrt(m);i++)
{
if(m % i == 0)
return false;
}
return true;
}
int main()
{
int n;
cin >> n;
int c = 0;
for(int i = 2;i <= n; i++)
{
//判断i是否是素数
if(is_prime(i))
c++;
}
cout << c << endl;
return 0;
}
练习八:素数对
B2132 素数对 - 洛谷
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
bool is_prime(int m)
{
if(m <= 1)
return false;
for(int i = 2 ; i <= sqrt(m) ; i++)
{
if(m % i == 0)
return false;
}
return true;
}
int main()
{
int n;
cin >> n;
int flag = 0;
//这里要 i+2 <= n ;不然会错解
for(int i = 2; i + 2 <= n ; i++)
{
if(is_prime(i) && is_prime(i+2))
{
cout << i << " " << i+2 << endl;
flag++;
}
}
if(flag == 0)
{
cout << "empty" << endl;
}
return 0;
}
练习九:素数回文数的个数
B2136 素数回文数的个数 - 洛谷
1)对于判断是否为素数,这里不再赘诉 , 前面两题都是有关素数的;
2 )判断是否为回文数 :
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
bool is_prime(int m)
{
if(m <= 1)
return false;
for(int i = 2; i<=sqrt(m);i++)
{
if(m % i == 0)
return false;
}
return true;
}
bool is_huiwen(int n)
{
int tmp = n;
int ret = 0;
while(tmp)
{
ret = ret * 10 + tmp % 10;
tmp /= 10;
}
return ret == n;
}
int main()
{
int n;
cin >> n;
int c = 0;;
for(int i = 11 ; i <= n;i++)
{
if(is_prime(i) && is_huiwen(i))
c++;
}
cout << c << endl;
return 0;
}
方法二:
运用我们万能的函数!!!
先 to_string , 把数字转化为字符串 , 然后reverse 字符串 , 然后判断反转后的 与 原始字符串是否相等 ;
注意 : reverse 需要头文件 <algorithm>
to_string 需要头文件<string>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
bool is_prime(int m)
{
if(m <= 1)
return false;
for(int i = 2; i<=sqrt(m);i++)
{
if(m % i == 0)
return false;
}
return true;
}
bool is_huiwen(int m)
{
string m1 = to_string(m);
string m2 = m1;
reverse(m1.begin(),m1.end());
return m1 == m2;
}
int main()
{
int n;
cin >> n;
int c = 0;;
for(int i = 11 ; i <= n;i++)
{
if(is_prime(i) && is_huiwen(i))
c++;
}
cout << c << endl;
return 0;
}
练习十:区间内的真素数
B2139 区间内的真素数 - 洛谷
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
bool is_prime(int m)
{
if(m <= 1)
return false;
for(int i = 2 ; i<= sqrt(m);i++)
{
if(m % i == 0)
return false;
}
return true;
}
int n_reverse(int x)
{
int ret = 0;
while(x)
{
ret = ret * 10 + x % 10;
x /= 10;
}
return ret;
}
int main()
{
int M,N;
int c = 0;
cin >> M >> N;
for(int i = M ; i <= N ;i++)
{
int n = n_reverse(i);
if(is_prime(i) && is_prime(n))
{
if(c)
cout << ",";
cout << i;
c++;
}
}
if( c == 0)
cout << "No" << endl;
return 0;
}