【35天从0开始备战蓝桥杯 -- Day5】

作者:小年糕是糕手日期:2026/3/24

🫧个人主页:小年糕是糕手

💫个人专栏:《C++》《Linux》《数据结构》《C语言》

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!


目录

一、输入输出

1.1、单组测试用例

1°计算 (a+b)/c 的值

2°与 7 无关的数

1.2、多组测试用例

情况一

1°多组输入a+b II

2°斐波那契数列

3°制糊串

情况二

1°多组输入a+b

2°数字三角形

3°定位查找

情况三

1°字符统计

拓展函数

2°多组数据a+b III

1.3、输入时的特殊技巧

1°含空格字符串的输入技巧 -- 统计数字字符个数

2°数字的特殊处理方式 -- 小乐乐改数字

1.4、scanf / printf与cin / cout的对比

1°格式控制差异

2°性能差异

数字游戏

求第 k 小的数

3°优化方案

二、函数

2.1、概述

1°普通参数

2°数组

3°字符串

4°全局变量

2.2、返回值

2.3、声明和定义

2.4、函数调用

1°传值调用

2°引用

3°效率比较

2.5、函数重载

练习

1°最大数 max(x,y,z)

拓展函数

max

min

2°求正整数 2 和 n 之间的完全数

3°素数个数

4°素数对

5°素数回文数的个数

6°区间内的真素数

三、递归

3.1、概述

3.2、典型案例解析

1°计算阶乘

迭代

递归

2°斐波那契数列

迭代

递归

练习


一、输入输出

前面我们学过了很多种输入输出,cin / cout、scanf / printf、getline、fgets等等,但是实际上的oj编程题中情况一般都是比较常见的几种,下面为大家做个小结并结合一些习题帮助大家更好理解

1.1、单组测试用例

**1°**计算 (a+b)/c 的值

计算 (a+b)/c 的值

1#include<iostream>
2using namespace std;
3int main()
4{
5    int a,b,c;
6    cin>>a>>b>>c;
7    int ret=(a+b)/c;
8    cout<<ret<<endl;
9    return 0;
10}

2°与 7 无关的数

与 7 无关的数

1#include<iostream>
2#include<cmath>
3using namespace std;
4int main()
5{
6	int n;
7	cin >> n;
8	int sum = 0;
9	int i = 1;
10	while (i <= n)
11	{
12		//判断i是否是和7无关
13		if ((i % 7 != 0) && (i % 10 != 7) && (i / 10 != 7))
14		{
15			sum += i * i;
16		}
17		i++;
18	}
19	cout << sum << endl;
20	return 0;
21}

相信通过前面的学习这两题的代码大家已经是信手拈来了,也没啥好解释的这两道题,只是让大家体会一下什么是单组测试用例,我们重点来看下面的内容:

1.2、多组测试用例

情况一

这部分我们来看测试数据组数已知的情况

1°多组输入a+b II

多组输入a+b II

1#include<iostream>
2using namespace std;
3int main()
4{
5    int n;
6    cin >> n;
7    int a, b;
8    int ret;
9    while (n--)
10    {
11        ret = 0;
12        cin >> a >> b;
13        ret = a + b;
14        cout << ret << endl;
15    }
16    return 0;
17}
2°斐波那契数列

斐波那契数列

这里我们提供两种思路,其实还有一种递归的思路,下面章节我们会学习,这里留个悬念,思路一我们是循环读取多组输入的数字a,对每个a用迭代法计算第a个斐波那契数并输出。

1#include<iostream>
2using namespace std;
3int main()
4{
5    int n;
6    cin>>n;
7    int a;
8    while(n--)//n次访问
9    {
10        cin>>a;
11        //计算第n个斐波那契数
12        int x = 1;
13        int y = 1;
14        int z = 1;
15        while (a > 2)
16        {
17        	z = x + y;
18        	x = y;
19        	y = z;
20        	a--;
21        }
22        cout << z << endl;
23    }
24   return 0; 
25}

思路二我们采用计算好前30个斐波那契数,存储到ret数组中,需要第几个就从下标几的位置去取

1#include <iostream>
2using namespace std;
3int main()
4{
5	int n = 0;
6	int a = 0;
7	int i = 0;
8	//计算好前30个斐波那契数,存储到ret数组中 
9	//需要第⼏个就从下标⼏的位置去取 
10	int ret[40] = { 0, 1, 1 };
11	for (i = 3; i < 30; i++)
12	{
13		ret[i] = ret[i - 1] + ret[i - 2];
14	}
15	cin >> n;
16	int z = 0;
17	while (n--)
18	{
19		cin >> a;
20		cout << ret[a] << endl;
21	}
22	return 0;
23}
**3°**制糊串

制糊串

1#include<iostream>
2#include<string>
3using namespace std;
4int main()
5{
6	string s, t;
7	cin >> s >> t;
8	string s1, t1;
9	int q, l1, r1, l2, r2;
10	cin >> q;
11	while (q--)
12	{
13		cin >> l1 >> r1 >> l2 >> r2;
14		s1 = s.substr(l1 - 1, r1 - l1 + 1);
15		t1 = t.substr(l2 - 1, r2 - l2 + 1);
16		//比较
17		if (s1 < t1)
18			cout << "yifusuyi" << endl;
19		else if (s1 > t1)
20			cout << "erfusuer" << endl;
21		else
22			cout << "ovo" << endl;
23	}
24	return 0;
25}

编程小技巧:

题目中说 “有 q 次询问”,意思是程序要处理 q 组测试数据,(也就是对应 q 次循环),我们要针对每次询问,给出一个结果。

其实就是之前的单组测试变成了 q 组测试,在之前的代码上套一层 while 循环即可。当有 q 次询问的时候,while (q--) 是非常方便的方式。然后就按照单组输入的方式处理每组输入的数据就好了

情况二

这部分我们来看测试数据组数未知的情况

1°多组输入a+b

多组输入a+b

1#include<iostream>
2using namespace std;
3int main()
4{
5    int a,b;
6    while(cin >> a >> b)
7    {
8        cout << a + b <<endl;
9    }
10    return 0;
11}

cin >> a; 会返回一个流对象的引用,即 cin 本身。在 C++ 中,流对象 cin 可以被用作布尔值来检查流的状态。如果流的状态良好(即没有发生错误),流对象的布尔值为 true。如果发生错误(如遇到输入结束符或类型不匹配),布尔值为 false


while (cin >> a >> b) 语句中,循环的条件部分检查 cin 流的状态。如果流成功读取到 2 个值,cin >> a >> b 返回的流对象 cin 将被转换为 true,循环将继续。如果读取失败(例如遇到输入结束符或无法读取到 2 个值),cin >> a >> b 返回的流对象 cin 将被转换为 false,循环将停止。

2°数字三角形

数字三角形

1#include<iostream>
2using namespace std;
3int main()
4{
5    int n;
6    while(cin >> n)
7    {
8        for(int i = 1;i <= n;i++)
9        {
10            for(int j = 1;j <= i;j++)
11            {
12                cout << j << ' ';
13            }
14            cout<<endl;
15        }
16        
17    }
18    return 0;
19}

这个题目其实很类似我们前面写过的,判断质数,乘法口诀表这类

3°定位查找

定位查找

这里为大家展示两种最常见的写法:

1#include<iostream>
2#include<cstring>
3using namespace std;
4int main()
5{
6    int n;
7    int arr[20] = {0};
8    while(cin >> n)
9    {
10        for(int i = 0;i < n;i++)
11        {
12            cin >> arr[i];
13        }
14        int m;
15        cin >> m;
16          
17        int pos = -1; // 标记位置
18        for(int j = 0; j < n; j++) // 从0开始遍历
19        {
20            if(arr[j] == m)
21            {
22                pos = j;
23                break; // 第一次出现就停止
24            }
25        }
26        
27        if(pos != -1)
28            cout << pos << endl;
29        else
30            cout << "No" << endl;
31        
32        memset(arr, 0, sizeof(arr));
33    }
34    return 0;
35}

我们来解释这第一段代码:我们定义了一个整型n,代表n组数据,然后定义了一个数组暂且全部初始化为0,下面我们进入while循环,定义了一个for循环来给这个数组赋值,下面定义并且输入一个m作为我们的要查找的值,下面定义了一个pos用来标记位置,然后我们遍历数组并且与m进行比较,如果找到了就跳出循环并且给pos位置赋值标记下标,如果没找到pos还是一开始的值,我们打印no即可,最后使用我们之前学过的memset给数组置为0即可

这个思路很简单,但是其实代码的水平不是很高,有点冗余,下面给出优化之后的解法:

1#include <iostream>
2using namespace std;
3const int N = 25;
4int arr[N];
5int main()
6{
7	int n = 0;
8	int m = 0;
9	while (cin >> n)
10	{
11		//输入n个数字,存放在arr中
12		for (int i = 0; i < n; i++)
13		{
14			cin >> arr[i];
15		}
16		//输入m
17		cin >> m;
18		int i = 0;
19		//在arr数组中查找m
20		for (i = 0; i < n; i++)
21		{
22		if (m == arr[i])
23		{
24			cout << i << endl;
25			break;
26		}
27	}
28	if (i == n)
29		cout << "No" << endl;
30}
31	return 0;
32}

这里我们舍弃了memset,因为这里其实根本不需要去清空数组,上一次的结果会被我们下一次直接覆盖,我们查找的范围也是根据元素个数来的,所以根本不需要重置数组。

情况三

这部分我们来看特殊值结束测试数据的情况

1°字符统计

字符统计

这题我们依旧有两种思路,我们可以逐个字符的读取,然后统计,这里可以使用getchar(),我们也可以一次性读取整个字符串然后统计

1#include<iostream>
2using namespace std;
3int Letters, Digits, Others;
4int main()
5{
6    int ch = 0;
7    while ((ch = getchar()) != '?')
8    {
9        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
10            Letters++;
11        else if (ch >= '0' && ch <= '9')
12            Digits++;
13        else
14            Others++;
15    }
16    cout << "Letters=" << Letters << endl;
17    cout << "Digits=" << Digits << endl;
18    cout << "Others=" << Others << endl;
19    return 0;
20}

这里将那几个参数定义为全局变量是因为:全局变量 / 静态变量 → 系统自动帮你赋值为 0

拓展函数

下面为大家介绍几个函数帮助大家简化代码:

1//头文件
2#include <cctype>
函数作用
isalpha(c)是否是字母(大小写都算)
islower(c)是否小写字母 -- 小写字母 a-z
isupper(c)是否大写字母 -- 大写字母 A-Z
isdigit(c)是否数字 -- 数字 0-9
isspace(c)是否空格、换行、制表符

返回值规则 完全一模一样

所有这 5 个函数的返回值规则:

  • 如果【是】 → 返回一个 非 0 的整数(真)
  • 如果【不是】 → 返回 0(假)

下面我们对代码进行优化:

1#include<iostream>
2#include<cctype>
3using namespace std;
4int Letters, Digits, Others;
5int main()
6{
7    int ch = 0;
8    while ((ch = getchar()) != '?')
9    {
10        if ((islower(ch)) || (isupper(ch)))
11            Letters++;
12        else if (isdigit(ch))
13            Digits++;
14        else
15            Others++;
16    }
17    cout << "Letters=" << Letters << endl;
18    cout << "Digits=" << Digits << endl;
19    cout << "Others=" << Others << endl;
20    return 0;
21}
1#include<iostream>
2#include<cctype>
3using namespace std;
4int Letters, Digits, Others;
5int main()
6{
7    int ch = 0;
8    while ((ch = getchar()) != '?')
9    {
10        if (isalpha(ch))
11            Letters++;
12        else if (isdigit(ch))
13            Digits++;
14        else
15            Others++;
16    }
17    cout << "Letters=" << Letters << endl;
18    cout << "Digits=" << Digits << endl;
19    cout << "Others=" << Others << endl;
20    return 0;
21}

下面我们来看方法二:

1#include<iostream>
2#include<string>
3using namespace std;
4int Letters, Digits, Others;
5int main()
6{
7	string s;
8	getline(cin, s, '?');
9	for (auto e : s)
10	{
11		if (isalpha(e))
12			Letters++;
13		else if (isdigit(e))
14			Digits++;
15		else
16			Others++;
17	}
18	cout << "Letters=" << Letters << endl;
19    cout << "Digits=" << Digits << endl;
20    cout << "Others=" << Others << endl;
21	return 0;
22}

这里需要注意我们之前介绍过的getline的第二种用法,其实还有一种方法就是使用getline的第一种写法,然后写个pop_back,也可以满足需求

2°多组数据a+b III

多组数据a+b III

1#include<iostream>
2using namespace std;
3int main()
4{
5    int a, b;
6    while (cin >> a >> b)
7    {
8        if (a == 0 && b == 0)
9            break;
10        cout << a + b << endl;
11    }
12    return 0;
13}

这里其实还有一种写法,利用到了逗号表达式:逗号隔开的一串表达式的特点:从左向右依次计算,整个表达式的结果是最后一个表达式的结果

1#include<iostream>
2using namespace std;
3int main()
4{
5    int a, b;
6    while (cin >> a >> b, a || b)
7    {
8        cout << a + b << endl;
9    }
10    return 0;
11}

1.3、输入时的特殊技巧

根据我们现在掌握的知识,含空格的字符串,如要读取有 fgetsscanfgetchargetline 四种方式解决,但是有时候,根据题目的情况,不一定非要完整的读取这个带空格的字符串,而是将字符串中空格隔开的每一个字符串,当做一个单词处理更方便,也避免了读取带空格字符串的各种问题。

1°含空格字符串的输入技巧 -- 统计数字字符个数

统计数字字符个数

这个题目其实与字符统计那个题目非常类似,我们依旧可以采取整个字符串一次性读取,然后处理字符串,也可以采取逐个单词的方式处理,下面给出两种方案的代码:

1#include<iostream>
2#include<string>
3using namespace std;
4int main()
5{
6    string s;
7    getline(cin, s);
8    int count = 0;
9    for (auto e : s)
10    {
11        if (isdigit(e))
12            count++;
13    }
14    cout << count << endl;
15    return 0;
16}
1#include<iostream>
2#include<string>
3using namespace std;
4int main()
5{
6    string s;
7    int count = 0;
8    while (cin >> s)
9    {
10        for (auto e : s)
11        {
12            if (isdigit(e))
13                count++;
14        }
15    }
16    cout << count << endl;
17    return 0;
18}

2°数字的特殊处理方式 -- 小乐乐改数字

小乐乐改数字

1#include<iostream>
2#include<cmath>
3#include<string>
4using namespace std;
5
6int main() {
7    int n;
8    cin >> n;
9    int i = 0; //标记⼀下此时处理到多少位
10    int ret = 0;
11    while (n) {
12        if (n % 10 % 2) //如果这⼀位是奇数
13            ret += 1 * pow(10, i);
14        else
15            ret += 0 * pow(10, i);
16        n /= 10; //把最后⼀位干掉
17        i++;
18    }
19    cout << ret << endl;
20    return 0;
21}

其实我们还有一种思路就是将输入的内容当做字符串处理:

1#include<iostream>
2#include<cmath>
3#include<string>
4using namespace std;
5
6int main() {
7    string s;
8    cin >> s;
9    for (int i = 0; i < s.size();i++)
10    { // 数字字符与对应的数的奇偶⼀致
11        if (s[i] % 2) 
12        {
13            s[i] = '1';
14        } 
15        else 
16        {
17            s[i] = '0';
18        }
19    }
20    cout << stoi(s) << endl; // 转换成数字输出
21    return 0;
22}

1.4、scanf / printf与cin / cout的对比

1°格式控制差异

  • scanfprintf 不能自动识别输入数据的类型,需要手动指定格式字符串,容易出现格式错误。开发者需要确保格式字符串与变量类型匹配,否则会导致未定义行为。
  • cincout 会根据变量类型自动处理输入输出,避免格式化错误。相对 scanfprintf 而且,C++ 的 cincout 更加易用。
  • scanfprintf:格式化输出更精确直观,特别适合复杂格式的输入输出,比如:在要求指定格式输出的时候,printf 函数就比 cout 更加方便和灵活。

区别

  1. cout 默认不会输出六位小数,自动忽略小数点后多余的 0,printf 函数打印浮点数的时候,小数点默认打印 6 位。
  2. cout 在输出的时候不需要指定格式,printf 则需要明确的格式。

2°性能差异

结论scanfprintf 通常比 cincout 快。


原因cincout 由于要考虑兼容 C 语言的输入和输出,封装实现的更加复杂,通常比 scanfprintf 稍慢,但这种差异在大多数应用场景中可以忽略不计。

但是在竞赛的题目中,尤其是当输入、输出数据量较大时,使用 cincout 完成输入输出,经常会出现 Time Limit Exceeded 的情况。而 scanfprintf 就不存在类似的问题。下面给大家准备了两个案例。

数字游戏

数字游戏

我们从这个题目的输入描述应该就不难看出这个题目的数据量是非常大的,题目也提示我们请选择较快的读入方式,下面给出两种输入方式所展现的代码,大家不用看懂代码只需要去对比一下性能差异即可:

1#include <iostream>
2using namespace std;
3int t, x;
4int main()
5{
6	cin >> t;
7	while (t--)
8	{
9		cin >> x;
10		int ret = 0;
11		while (x)
12		{
13			int count = 0, high = 0;
14			int tmp = x;
15			while (tmp)
16			{
17				//计算最右边的1代表的值
18				int low = tmp & -tmp;
19				//如果low中剩余的1就是最后⼀个1就是最左边的1 
20				if (tmp == low)
21				{
22					high = low;
23				}
24				//去掉最右边的1 
25				tmp -= low;
26				count++;
27			}
28			if (count % 2 == 0)
29			{
30				x -= high;
31			}
32			else
33			{
34				x ^= 1;
35			}
36			ret++;
37		}
38		cout << ret << endl;
39	}
40	return 0;
41}
42
1#include <iostream>
2using namespace std;
3int t, x;
4int main()
5{
6	scanf("%d", &t);
7	while (t--)
8	{
9		scanf("%d", &x);
10		int ret = 0;
11		while (x)
12		{
13			int count = 0, high = 0;
14			int tmp = x;
15			while (tmp)
16			{
17				//计算最右边的1代表的值
18				int low = tmp & -tmp;
19				//如果low中剩余的1就是最后⼀个1就是最左边的1 
20				if (tmp == low)
21				{
22					high = low;
23				}
24				//去掉最右边的1 
25				tmp -= low;
26				count++;
27			}
28			if (count % 2 == 0)
29			{
30				x -= high;
31			}
32			else
33			{
34				x ^= 1;
35			}
36			ret++;
37		}
38		printf("%d\n", ret);
39	}
40	return 0;
41}
42

这是两次的运行时间大家很明显就可以看出差异了

求第 k 小的数

求第 k 小的数

这题我们依旧采用两种输入输出方式进行提交,我们来看看有什么区别:

1#include <iostream>
2#include <cstdio>
3#include <algorithm>
4using namespace std;
5const int N = 5000010;
6int arr[N];
7int main()
8{
9	int n, k;
10	cin >> n >> k;
11	for (int i = 0; i < n; i++)
12	{
13		cin >> arr[i];
14	}
15	sort(arr, arr + n);
16	cout << arr[k] << endl;
17	return 0;
18}
19

我们发现超时了,下面我们一种输入输出方式:

1#include <iostream>
2#include <cstdio>
3#include <algorithm>
4using namespace std;
5const int N = 5000010;
6int arr[N];
7int main()
8{
9	int n, k;
10	cin >> n >> k;
11	for (int i = 0; i < n; i++)
12	{
13		scanf("%d", &arr[i]);
14	}
15	sort(arr, arr + n);
16	cout << arr[k] << endl;
17	return 0;
18}

总结一下其实就是 2 个点:

  1. C++ 中为了支持混合使用 cin/coutscanf/printf,C++ 标准库默认会将 cincout 等 C++ 流对象与 stdinstdout 等 C 标准库的流对象同步在一起。这种同步操作意味着每次使用 cincout 时,都会自动刷新 C 标准库的缓冲区,以确保 C++ 和 C 的 I/O 是一致的。这就导致了性能的下降。
  2. 在默认情况下,cincout 之间存在一种绑定关系。这种绑定意味着,每当从 cin 读取数据时,任何之前通过 cout 输出的内容都会被强制刷新到屏幕上。这种绑定也可能导致性能问题,特别是在需要频繁读取大量数据的情况下。

3°优化方案

如果大家还是想要去使用cin和cout也不是不可以只需要加上下面三行代码即可:

1//在io需求⽐较⾼的地⽅,如部分⼤量输⼊的竞赛题中,加上以下3⾏代码 
2//可以提⾼C++IO效率 
3ios_base::sync_with_stdio(false);//取消给C语⾔输⼊输出缓冲区的同步
4cin.tie(nullptr);//取消了cin和cout的绑定
5cout.tie(nullptr);
6

二、函数

2.1、概述

为大家准备了一篇可以精准解决函数基础概念及基本语法的博客:

【C语言】C语言函数大揭秘:开启编程魔法的钥匙_编程需要用到函数吗-CSDN博客https://blog.csdn.net/2501_91731683/article/details/147687142

1°普通参数

下面为大家强调一些关键点,我们首先来看一个简单的加法函数:

1#include<iostream>
2using namespace std;
3int Add(int x, int y)
4{
5	int z = 0;
6	z = x + y;
7	return z;
8}
9int main()
10{
11	int a = 0;
12	int b = 0;
13	//输⼊ 
14	cin >> a >> b;
15	//调⽤加法函数,完成a和b的相加 
16	//求和的结果放在r中 
17	int r = Add(a, b);
18	//输出 
19	cout << r << endl;
20	return 0;
21}

我们首先是对Add函数有个定义,有了函数之后我们下面调用Add函数的时候,传递给函数的参数a和b称为实际参数,也就是我们常说的实参;定义函数的时候,在函数名Add后的括号中写的x和y,称为形式参数,简称形参。

为什么叫形式参数呢?实际上,如果只是定义了 Add 函数,而不去调用的话,Add 函数的参数 xy 只是形式上存在的,不会向内存申请空间,不会真实存在的,所以叫形式参数。形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形式的实例化。虽然我们提到了实参是传递给形参的,他们之间是有联系的,但是形参和实参各自是独立的内存空间。

我们在调试的可以观察到,xy 确实得到了 ab 的值,但是 xy 的地址和 ab 的地址是不一样的,当 ab 传参给形参 xy 的时候,xy 只是得到了 ab 的值,他们得有自己独立的空间。所以我们可以理解为形参是实参的一份临时拷贝

简单概括一下就是:形参不用就不占空间,用了就去额外开辟空间(地址不同,形参实参互不影响),形参是实参的一份临时拷贝

2°数组

当我们将函数和数组练习起来的时候就要注意下面的几点:

  • 函数的实参的名字和形参的名字可以相同,也可以不同
  • 函数的形式参数要和函数的实参个数匹配
  • 函数的实参是数组,形参也写成数组形式的
  • 形参如果是一维数组,数组大小可以省略不写
  • 形参如果是二维数组,行可以省略,但是列不能省略
  • 数组传参,形参是不会创建新的数组的
  • 形参操作的数组和实参的数组是同一个数组

简单一句话概括就是:函数实参和形参名字可同可不同、个数要匹配;数组传参时形参不新建数组,直接操作原数组,一维形参数组大小可省略,二维只能省略行不能省略列。

数组传参时,形参不会创建新数组,所以形参数组不需要指定大小!但是不可以写成int arr,这样会认为是一个整型变量而不是数组

3°字符串

一句话直接概括就是:字符串传参:普通字符串形参是临时拷贝,修改不影响实参

4°全局变量

全局变量的作用域很大,在整个程序中都可以使用,那么只要把变量、数组等定义成全局变量,在函数中使用,是可以不用传参的。

当然,有时候变量或者数组,定义成全局的时候,是不能解决问题,比如:递归等场景,这时候,就得考虑传参的问题,后面会为大家讲解

2.2、返回值

这里我们只说一点:return语句执行后,函数就彻底返回,后边的代码不再执行:

2.3、声明和定义

我们首先来看一下什么是函数声明什么是函数定义:

1//函数声明
2int Add(int x, int y);
3
4//函数定义
5int Add(int x, int y)
6{
7	return x + y;
8}

声明放前面,定义放后面,主函数能正常调用:

函数使用的时候要注意:1)函数要满足先声明后使用;2)函数的定义是一种特殊的声明;3)函数声明的时候形参的变量名是可以省略的,只保留类型即可:

2.4、函数调用

1°传值调用

写一个1函数Max,求两个整数的较大值:

1#include <iostream>
2using namespace std;
3int Max(int x, int y)
4{
5	return x > y ? x : y;
6}
7int main()
8{
9	int a = 0;
10	int b = 0;
11	cin >> a >> b;
12	int c = Max(a, b);
13	cout << c << endl;
14	return 0;
15}
16

调用Max函数时,就是传值调用。传值调用就是将实参的数据直接传递给形参。这个过程其实是将实参的值拷贝一份给Max函数使用,这份副本其实就是形参变量。这时形参和实参是不同的变 量,所以对形参的修改,不会影响实参。这种情况下参数传递的方式只能从实参到形参,也就是单向传递。为了理解什么是单向传递,我们看一下下面一个函数:

写一个函数Swap,交换两个整型变量的值:

我们发现函数的思路没有任何问题但是代码结果却和我们想的完全不一样,这是为什么呢?

其实 Swap 函数里的 xy 确实会交换,但 main 里的 ab 丝毫未变。这就是值传递的特点:形参与实参占用不同内存,对形参的修改不会影响实参,数据单向传递,因此交换失败。一句话概括:xy 是独立空间,交换它们不等于交换 ab

那怎么样才能实现交换呢?下面我们就来看看C++中的引用:

2°引用

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量是同一块内存空间

类型& 引用别名 = 引用对象


  • 引用在定义时必须初始化
  • 一个变量可以有多个引用
  • 引用一旦引用一个实体,再不能引用其他实体

引用就相当于个一个变量起一个别名:

1#include<iostream>
2using namespace std;
3int main()
4{
5	int a = 0;
6	// 引⽤:b和c是a的别名 
7	int& b = a;
8	int& c = a;
9	// 也可以给别名b取别名,d相当于还是a的别名 
10	int& d = b;
11	++d;
12	// 这⾥取地址我们看到是⼀样的 
13	cout << &a << endl;
14	cout << &b << endl;
15	cout << &c << endl;
16	cout << &d << endl;
17	return 0;
18}

我们来看运行结果发现是一模一样的,我们就相当于给一块空间取了一个名字和三个别名,就类似于家人给我们取的小名一样,他们喊大名或者小名本质上就是在喊我们:

下面我们来对swap函数进行更改:

我们现在就实现了Swap交换函数,其实C++STL中也提供了一个库函数swap,这个函数可以用来交换两个变量也可以交换两个数组(容器的值):

1#include <iostream>
2#include <utility>
3using namespace std;
4int main()
5{
6	int a = 0;
7	int b = 0;
8	cin >> a >> b;
9	cout << "交换前, a = " << a << " b = " << b << endl;
10	swap(a, b);//直接使⽤库函数swap交换两个变量 
11	cout << "交换后, a = " << a << " b = " << b << endl;
12
13	//swap也可以交换两个数组
14	int arr1[4]; // arr1: 0 0 0 0
15	int arr2[] = { 10,20,30,40 }; // arr1: 0 0 0 0  arr2: 10 20 30 40
16	swap(arr1, arr2); // arr1: 10 20 30 40 arr2: 0 0 0 0
17
18	for (int e : arr1)
19		cout << e << " ";
20	cout << endl;
21
22	return 0;
23}

那么字符串能不能使用引用的方式传参呢?当时是可以的:

1#include <iostream>
2using namespace std;
3void printString(string& s)
4{
5	cout << s << endl;
6	s = "zhui ming zhen zhou";
7}
8int main()
9{
10	string s("hello world");
11	printString(s);
12	cout << s << endl;
13	return 0;
14}

3°效率比较

采用传值调用过程中,函数传参,将实参传递给形参的时候,形参会创建新的空间,再将实参的数据给形参拷贝一份;但是引用传参的方式,就不存在数据的拷贝,只是在形参的部分建立引用的关系,形参就是实参。所以引用传参的效率要高于传值调用的方式。


💡小提示:数组在传参的时候,形参和实参本来就是同一个数组,所以数组传参的时候,不需要使用引用参数。

2.5、函数重载

函数重载 + 引用巩固超详细版:

【C++】C++入门 -- 函数重载、引用_c++ 重载引用符号-CSDN博客https://blog.csdn.net/2501_91731683/article/details/154997756?spm=1001.2014.3001.5501

练习

关于函数的题目其实非常多这里为大家挑选一些较为典型的案例:

1°最大数 max(x,y,z)

最大数 max(x,y,z)

1#include<iostream>
2#include<iomanip>
3using namespace std;
4
5int MAX(int x, int y, int z)//存储最大值
6{
7	int m = x > y ? x : y;
8	return m > z ? m : z;
9}
10
11int main()
12{
13	int a, b, c;
14	cin >> a >> b >> c;
15	double m = ((double)MAX(a, b, c) / ((MAX(a + b, b, c) * MAX(a, b, b + c))));
16	cout << fixed << setprecision(3) << m << endl;
17
18	return 0;
19}
拓展函数

这里为大家拓展库函数max和min:

max

max

在 C++ 中,max 函数用于返回两个值中的较大值。它是 C++ 标准库 <algorithm> 头文件中的一个函数。

max 函数可以用于各种类型,包括内置类型(如 intdouble)以及用户自定义类型(如类或结构体),只要这些类型支持比较操作。


1#include <algorithm>
2template <class T>
3const T & max(const T & a, const T & b); //默认⽐较 
4template <class T, class Compare>
5const T& max(const T& a, const T& b, Compare comp); //⾃定义⽐较器

参数:

  1. a:要比较的第一个值。
  2. b:要比较的第二个值。
  3. comp(可选):自定义比较函数对象或比较函数,用于确定 “较大” 值的标准。
  4. 比较函数应当返回一个布尔值,表示第一个参数是否 “小于” 第二个参数。

返回值:

  • 返回 ab 中较大的那个值。如果两个值相等,则返回 a

总结

使用 max 库函数需要包含 <algorithm> 头文件。对于整型、浮点型等基础数据类型,可以直接使用 max 函数比较大小;但在特殊场景下(如自定义结构体、类、字符串比较规则等),库函数无法满足需求,需要自定义比较规则来实现大小比较。

1#include <iostream>
2#include <algorithm>
3using namespace std;
4int main()
5{
6	int x = 10;
7	int y = 20;
8	int m = max(x, y);
9	cout << "较大值是: " << m << endl;
10
11	return 0;
12}
1#include <iostream>
2#include <algorithm>
3#include <string>
4using namespace std;
5bool compareLength(const string& a, const string& b)
6{
7	return a.size() < b.size(); //这⾥必须给⼀个判断⼩于的标准 
8}
9int main()
10{
11	string str1 = "apple";
12	string str2 = "banana";
13	string max_str = max(str1, str2, compareLength);
14	cout << "长度更长的字符串是" << max_str << endl;
15
16	return 0;
17}
min

在 C++ 中,min 函数用于返回两个值中的较小值。它和 max 函数类似,也是在 C++ 标准库 <algorithm> 头文件中的一个函数。使用和 max 函数一模一样,只是实现的效果恰好相反。

1#include <iostream>
2#include <algorithm>
3#include <string>
4using namespace std;
5bool compareLength(const string& a, const string& b)
6{
7	return a.size() < b.size(); //这⾥必须给⼀个判断⼩于的标准 
8}
9int main()
10{
11	string str1 = "apple";
12	string str2 = "banana";
13	string min_str = min(str1, str2, compareLength);
14
15	cout << "长度更短的字符串是" << min_str << endl;
16	return 0;
17}
18

学完了之后我们可以对这题的代码进行优化:

1#include<iostream>
2#include<iomanip>
3#include<algorithm>
4using namespace std;
5
6int MAX(int x, int y, int z)//存储最大值
7{
8	int m = max(x, y);
9	return max(m, z);
10}
11
12int main()
13{
14	int a, b, c;
15	cin >> a >> b >> c;
16	double m = ((double)MAX(a, b, c) / ((MAX(a + b, b, c) * MAX(a, b, b + c))));
17	cout << fixed << setprecision(3) << m << endl;
18
19	return 0;
20}

2°求正整数 2 和 n 之间的完全数

求正整数 2 和 n 之间的完全数

1#include<iostream>
2using namespace std;
3// 求n的所有因数之和
4int sumFactor(int n) 
5{
6    int sum = 0;
7    for (int i = 1; i < n; i++) 
8    {
9        if (n % i == 0) {  // 如果 i  n 的因数
10            sum += i;      // 加到总和里
11        }
12    }
13    return sum;
14}
15int main()
16{
17	int n;
18	cin >> n;
19    for (int i = 2; i <= n; i++)
20    {
21        if (i == sumFactor(i))
22            cout << i << endl;
23    }
24	return 0;
25}

3°素数个数

素数个数

素数也叫质数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数:

1#include <iostream>
2using namespace std;
3// 判断素数:是素数返回 true,不是返回 false
4bool check_prime(int m)
5{
6    for (int i = 2; i < m; i++)
7    {
8        if (m % i == 0)  // 能被整除  不是素数
9            return false;
10    }
11    return true; // 循环结束都没整除  是素数
12}
13int main()
14{
15    int n;
16    cin >> n;
17    int count = 0;
18    for (int i = 2; i <= n; i++)
19    {
20        if (check_prime(i)) // 是素数  计数
21        {
22            count++;
23        }
24    }
25    cout << count << endl;
26    return 0;
27}

其实判断素数还有一种方式我们去利用sqrt()函数:

1#include <iostream>
2#include <cmath>   //  sqrt 必须加这个头文件
3using namespace std;
4// 判断素数:是素数返回 true,不是返回 false
5bool check_prime(int m)
6{
7    // 原来:i < m
8    // 现在:i <= sqrt(m)  (优化核心)
9    for (int i = 2; i <= sqrt(m); i++)  
10    {
11        if (m % i == 0)  // 能被整除  不是素数
12            return false;
13    }
14    return true; // 循环结束都没整除  是素数
15}
16int main()
17{
18    int n;
19    cin >> n;
20    int count = 0;
21    for (int i = 2; i <= n; i++)
22    {
23        if (check_prime(i)) // 是素数  计数
24        {
25            count++;
26        }
27    }
28    cout << count << endl;
29    return 0;
30}

4°素数对

素数对

1#include <iostream>
2#include <cmath>
3using namespace std;
4bool is_prime(int n)
5{
6	int j = 0;
7	if (n < 2)
8		return false;
9	for (j = 2; j <= sqrt(n); j++)
10	{
11		if (n % j == 0)
12			return false;
13	}
14	return true;
15}
16int main()
17{
18	int n = 0;
19	cin >> n;
20	int i = 0;
21	int flag = 0;
22	for (i = 2; i + 2 <= n; i++)
23	{
24		if (is_prime(i) && is_prime(i + 2))
25		{
26			cout << i << " " << i + 2 << endl;
27			flag++;
28		}
29	}
30	if (flag == 0)
31		cout << "empty" << endl;
32	return 0;
33}
34

5°素数回文数的个数

素数回文数的个数

1#include<iostream>
2#include<cmath>
3#include<string>
4using namespace std;
5//判断是否是素数
6bool isPrime(int m)
7{
8    if (m < 2)
9        return false;
10	for (int i = 2; i <= sqrt(m); i++)
11	{
12		if (m % i == 0)
13			return false;
14	}
15	return true;
16}
17//判断是否是回文数
18bool ispalindrome(int m)
19{
20	int ret = m;
21	//将数字转换成字符
22	string s = to_string(ret);
23	int left = 0;
24	int right = s.size() - 1;
25	while (left < right)
26	{
27		char tmp = s[left];
28		s[left] = s[right];
29		s[right] = tmp;
30		left++;
31		right--;
32	}
33	//将字符转换成数字
34	int num = stoi(s);
35	if (num == m)
36		return true;
37	else
38		return false;
39}
40int main()
41{
42	int n;
43	cin >> n;
44	int count = 0;//统计个数
45	for (int i = 11; i <= n; i++)
46	{
47		if (isPrime(i) && ispalindrome(i))
48			count++;
49	}
50	cout << count << endl;
51	return 0;
52}

这是我第一遍写的代码,这段代码完全可以跑对这题但是其实还有优化的地方,比如回文数判断按那里我的做法是将数字先转换成string类型的字符串让他有下标然后去对比,最后转换成原数字和之前的数字比较,但是其实可以不用这么麻烦,回文数判断没必要反转 + 转数字,回文数不要反转再转数字,直接比较对称字符大家可以自行去尝试优化一下

6°区间内的真素数

区间内的真素数

1#include<iostream>
2#include<string>
3#include<cmath>
4using namespace std;
5bool isPrime(int m)
6{
7	if (m < 2)
8		return false;
9	for (int i = 2; i <= sqrt(m); i++)
10	{
11		if (m % i == 0)
12			return false;
13	}
14	return true;
15}
16// 反序后判断是否为素数
17bool reversePrime(int m)
18{
19    string s = to_string(m);
20    int left = 0;
21    int right = s.size() - 1;
22    while (left < right)
23    {
24        char tmp = s[left];
25        s[left] = s[right];
26        s[right] = tmp;
27        left++;
28        right--;
29    }
30    int ret = stoi(s);
31    return isPrime(ret);
32}
33int main()
34{
35    int M, N;
36    cin >> M >> N;
37    int flag = 1;   // 标记是否为第一个输出
38    int cnt = 0;    // 统计真素数个数
39    for (int i = M; i <= N; i++)
40    {
41        if (isPrime(i) && reversePrime(i))
42        {
43            cnt++;
44            if (flag)
45            {
46                cout << i;
47                flag = 0;
48            }
49            else
50            {
51                cout << "," << i;
52            }
53        }
54    }
55    // 若无真素数,输出 No
56    if (cnt == 0)
57        cout << "No";
58    cout << endl;
59    return 0;
60}

我写的代码基本都已可以看懂并且跑出题目为准,要是想要优化提升效率还需大家自己去尝试,后面C++的内容我也会为大家出一篇博客有关提升代码效率,大家可以期待一下,以上就是函数部分的简单内容,还是需要大家多刷题才能更好掌握

三、递归

3.1、概述

为大家准备了一篇可以初步了解递归的博客(大家直接看递归的内容即可):

【C语言】C语言特别篇--数组与函数的实践 + 函数递归_c语言数组判断函数-CSDN博客https://blog.csdn.net/2501_91731683/article/details/147690415

3.2、典型案例解析

1°计算阶乘

计算阶乘

我们用递归和迭代两种方式为大家解决:

迭代
1#include<iostream>
2using namespace std;
3int main()
4{
5	int n;
6	cin >> n;
7	int sum = 1;
8	for (int i = 1; i <= n; i++)
9	{
10		sum *= i;
11	}
12	cout << sum << endl;
13	return 0;
14}
递归
1#include<iostream>
2using namespace std;
3int fac(int n)
4{
5	if (n == 0)
6		return 1;
7	else
8		return n * fac(n - 1);
9}
10int main()
11{
12	int n;
13	cin >> n;
14	cout << fac(n) << endl;
15	return 0;
16}

这里还是要提醒大家一下:注意递归的中止条件,不然代码会有死循环、程序崩溃等问题

递归在书写的时候,有2个必要条件:

<1>、递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。

<2>、每次递归调用之后越来越接近这个限制条件。

2°斐波那契数列

斐波那契数列

我们依旧使用递归与迭代两种方式为大家解决:

迭代
1#include<iostream>
2using namespace std;
3int main()
4{
5	int n;
6	cin >> n;//数据组数
7	while (n--)
8	{
9		int m;//第几个斐波那契数
10		cin >> m;
11		int x = 1; int y = 1;
12		int z = 0;
13		if (m == 1 || m == 2)
14			cout << 1 << endl;
15		else
16		{
17			while (m > 2)
18			{
19				m--;
20				z = x + y; // 先把新数算出来(保存旧数据)
21				x = y;     // 再挪
22				y = z;     // 最后更新
23			}
24			cout << z << endl;
25		}
26	}
27	return 0;
28}
递归
1#include<iostream>
2using namespace std;
3int Fac(int m)
4{
5	//m表示第几个斐波那契数
6	if (m == 1 || m == 2)
7		return 1;
8	else
9		return Fac(m - 1) + Fac(m - 2);
10}
11int main()
12{
13	int n;
14	cin >> n;//数据组数
15	while (n--)
16	{
17		int m;//m表示第几个斐波那契数
18		cin >> m;
19		cout << Fac(m) << endl;
20	}
21	return 0;
22}

💡 核心结论先放这

递归 ≈ 层层套娃,占地方,容易炸 循环 ≈ 原地转圈,省空间,更高效


📦 通俗解释:函数调用和栈帧

你可以把内存的栈区想象成一个摞盘子的架子

  • 每调用一次函数,就往架子上放一个新盘子(这个盘子就是「栈帧」,用来放这个函数里的临时变量)。
  • 函数执行完返回了,才把这个盘子拿走,空间还给系统。

🔄 递归为什么费空间、容易炸?

递归就是自己调用自己,相当于:

  • 你先放了一个盘子(第一层函数)
  • 还没拿走,又在上面放一个(第二层递归调用)
  • 再放一个、再放一个…… 一直摞到很深
  • 直到最后一层函数才开始返回,然后从顶往下一个一个拿走盘子

如果递归层数太多,盘子摞得太高,就会把架子压垮—— 这就是「栈溢出(stack overflow)」,程序直接崩溃。


🔁 循环为什么更高效?

循环是在同一个函数里反复跑逻辑

  • 只需要一开始放一个盘子(整个循环都用这一个盘子)
  • 变量在同一个空间里反复覆盖更新,不会额外占更多盘子
  • 没有频繁的「放盘子 / 拿盘子」开销,所以更快、更省内存

✅ 什么时候用递归?什么时候用循环?

  • 优先用循环:大部分问题(比如计数、遍历),循环效率更高,不会有栈溢出风险。
  • 递归更适合:逻辑特别复杂、用循环写会非常绕的场景(比如树的遍历、分治算法)。这时候递归代码更简洁、更好懂,哪怕多占一点内存、慢一点,也是值得的。

📌 一句话总结

  • 递归:代码好写,但费内存,深度大了容易崩。
  • 循环:代码可能稍繁琐,但省内存、跑得快,更稳定。
  • 简单问题用循环,复杂问题用递归,看场景选就行。

还有一题和上述的非常类似,大家可以练练手:

求 1+2+3+...+N 的值

1#include<iostream>
2using namespace std;
3int Fac(int m)
4{
5	if (m < 1)
6		return 0;
7	else
8		return Fac(m - 1) + m;
9
10}
11int main()
12{
13	int N;
14	cin >> N;
15	int ret = Fac(N);
16	cout << ret << endl;
17	return 0;
18}

练习

https://www.luogu.com.cn/problem/B2144

https://www.luogu.com.cn/problem/B2145

https://www.luogu.com.cn/problem/B2147

https://www.luogu.com.cn/problem/B2148

https://www.luogu.com.cn/problem/B2143



【35天从0开始备战蓝桥杯 -- Day5】》 是转载文章,点击查看原文


相关推荐


OpenClaw“小龙虾”深度解析:60天碾压Linux的AI智能体,从原理到搞定本地部署【Windows系统 + 接入飞书】
燃于AC之乐2026/3/16

👇点击进入作者专栏: 《算法画解》 ✅ 《linux系统编程》✅ 《C++》 ✅ OpenClaw“小龙虾”深度解析:60天碾压Linux的AI智能体,从原理到搞定本地部署【Windows系统 + 接入飞书】 引言:2026年最火爆的开源AI智能体一、OpenClaw是什么?——从“对话”到“动手”的质变1.1 核心定位:长了手脚的大模型1.2 核心能力:一键控制电脑 二、技术原理:AI如何真正“动手干活”?2.1 架构设计2.2 工作流程2.3 技术关键点:上下文窗口压


dt/dd表格解析、URL拼接缺失、ON DUPLICATE字段覆盖、CSS选择器定位——俄罗斯轮胎展爬虫四大技术难关攻克纪实
进击的雷神2026/3/8

一、引言 在俄罗斯展会网站采集中,莫斯科轮胎及橡胶展览会(Expocentr)的网站采用了典型的表格布局和dt/dd结构存储展商信息。本文以该展会参展商信息采集项目为例,深入剖析在开发过程中遇到的四大技术难题,以及我们如何通过创新的技术方案逐一攻克这些难关。 二、技术难点全景图 #mermaid-svg-T86ttY9To1T8fJpx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill


三月,我只想做好这四件事
修己xj2026/2/28

今天是二月的最后一天,也是春节后上班第一周的收官之日。 在我们中国人的观念里,只有过完春节,新的一年才算真正开始。往年的这个时候,我总会兴致勃勃地立下一堆flag,制定满满当当的年度计划。虽然年终盘点时发现大部分都没实现,但来年依旧乐此不疲——仿佛只要把计划写得够漂亮,生活就会自动变好。 但今年不一样了。 家里添了一位新成员,我的身份悄然发生了改变。抱着怀里这个两个月大的小家伙,我突然不想再立那些宏大的flag,也不想做那些看似充实却往往落空的计划了。 一年很长,长到要数着日历过365个日夜;


C# WPF canvas中绘制缺陷分布map并实现缩放
zls3653652026/2/19

1、前台xaml 这里把canvas包裹在scrollviewer里面是为了避免滚轮缩放时canvas超出划定的区域,导致显示异常。 2. 后台代码: -. canvas load事件,主要用来获取控件的长度和宽度 -. canvas_mousewheel(object sender,MouseWheelEventArgs e)这个事件主要功能是为了实现通过鼠标进行canvas控件的缩放 -. 这里的逻辑主要为了实现缺陷分布图上的缺陷通过x进行标注 -.深度拷


AI 视觉连载3:RGB与通道
董章鱼是个攻城狮2026/2/11

在2、灰度与色彩的最后,给出了一个由彩色图片转成灰度图的示例,并且通过 color_image.mode获取了图片的格式:彩色图片获取到的格式为 RGBA,灰度图为 L。 这一节再介绍一下 RGB 图片以及通道的概念。 通道这个概念,在 深度学习 中很重要,并且极为重要。 举个例子—— 在很多时候,对AI神经网络中的一些算法做工程化实现,或者做性能优化,除了关注算法本身之外,还会关注数据存储格式。 一般在 pytorch 中(一个AI模型框架),数据的存储格式 NCHW, C指代的就是通道(ch


自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel
NBhhbYyOljP2026/2/2

自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel。 打开MATLAB准备搞点数据魔法?今天咱们整点有意思的——用自组织特征映射(SOM)给Excel数据自动分群。这玩意儿就像给数据画美食地图,让相似的样本自动抱团取暖。 先来点准备工作。把Excel数据塞进MATLAB最直接的方式就是readtable函数: data = readtable('你的数据.xlsx'); raw_data = table2array(data(:,2:end)); % 假设第


iOS 常用调试工具大全-打造你的调试武器库
sweet丶2026/1/24

还记得你第一次使用NSLog(@"Hello, World!")的时刻吗?那是调试的起点。但随着应用复杂度呈指数级增长,我们需要的工具也经历了革命性进化: 第一代:基础输出(NSLog、print) 第二代:图形化界面(Xcode调试器、Instruments) 第三代:运行时动态调试(FLEX、Lookin) 第四代:智能化监控(性能追踪、自动化检测) 今天,一个成熟的iOS开发者工具箱中,至少需要掌握3-5种核心调试工具,它们就像外科医生的手术刀——精准、高效、各有所长。 一、运行时调试


SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
普通网友2026/1/15

目录 一、前言二、版本选择和适配 2.1、本文使用各组件版本2.2、官方推荐版本 三、部署sentinel-dashboard 3.1、下载 sentinel-dashboard jar包3.2、启动 sentinel-dashboard 四、Gateway 集成 Sentinel实现控制台配置流控规则测试 4.1、添加Gateway 集成 Sentinel 包4.2、添加 Gateway 服务启动JVM参数 4.2.1、配置说明4.2.2、


一文讲清:主流大模型推理部署框架:vLLM、SGLang、TensorRT-LLM、ollama、XInference
智泊AI2026/1/7

本文系统性梳理当前主流的大模型推理部署框架,包括vLLM、SGLang、TensorRT-LLM、Ollama、XInference等。 随着大语言模型技术的迅猛演进,推理部署框架作为贯通模型能力与落地应用的核心枢纽,其战略价值正持续攀升。本文旨在对当前业界广泛采用的 vLLM、SGLang、TensorRT-LLM、Ollama 与 XInference 等主流推理框架展开系统性归纳,围绕核心技术路径、系统架构设计、关键性能指标及典型适用场景等多维度进行深度剖析,为大模型在生产环境中的选型决策


HarmonyOS官方模板集成创新活动-流蓝卡片
万少 VIP.5 如鱼得水2025/12/30

HarmonyOS官方模板集成创新活动-流蓝卡片 ​ 介绍 ​ ​ 流蓝卡片是一款适配了的鸿蒙6-API20的HarmonyOS应用,目的在于给用户提供方便、简单的方式创建好看的卡片,用于将卡片发布到各种社交平台上。 实现过程 ​ ​ 目前是AI Codeing的时代,流蓝卡片其实也是基于AI Coding的产物,人工参与代码部分不超过5%。 ​ 这款应用用到的亮点技术有:GLM4.6 + Gemini-3-pro + 智谱图片生成 + command line 构建鸿蒙工程。 ​ 这套技术组

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客