蓝桥备赛(七)- 函数与递归(中)

发布于:2025-03-03 ⋅ 阅读:(19) ⋅ 点赞:(0)

一、函数重载

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;
}