
个人主页:
个人专栏:
C语言
嵌入式小白启动!
重要OJ算法题详解
文章目录
前言
第十七届蓝桥杯软件赛C/C++组将于2026年4月11日举行,目前仅剩不到一个半月的时间来进行备战。那么我们需要准备些什么呢?跟着作者一起来进行探讨吧!
我们首先应该具备的知识是C/C++的基础语法知识。
一. 分析大纲,了解所需
我们可以在蓝桥杯官网中找到 **“第十七届蓝桥杯大赛软件赛(编程类)竞赛大纲”**这份文档。
1. 大纲显示内容





从组别划分、知识点结构、难度体系三个方面展开。
2、组别划分与难度关系
| 组别 | 适用对象 | 知识点范围说明 | 难度系数范围 |
|---|---|---|---|
| 大学C组 | 高职高专或基础较弱学生 | 基础语法、常用算法入门 | 1–5 |
| 大学B组 | 普通本科生 | 在C组基础上扩展中级算法与数据结构 | 4–7 |
| 大学A组 | 重点高校/研究生 | 涵盖C、B组内容,并增加高难度专题 | 7–10 |
| 研究生组 | 研究生 | 与A组共享高级内容,题型更具挑战性 | 7–10 |
说明:A组和研究生组的知识点基本相同,A组更强调综合应用,研究生组可能更注重理论深度和复杂度。
3、知识点结构分析(按组别)
3.1 大学C组:基础入门阶段
重点掌握:
- 枚举、排序(冒泡、选择、插入)
- 搜索(BFS/DFS)
- 贪心、模拟、二分
- DP(一维简单问题)
- 高精度、栈/队列/链表
- 基础数学
学习建议:
- 以刷题为导向,熟练掌握基本语法和简单算法。
- 推荐练习平台:洛谷、AcWing 基础题库。
3.2 大学B组:中级提高阶段
新增内容:
- 排序进阶(归并、快速、桶、堆、基数)
- 搜索优化(剪枝、双向BFS、记忆化、迭代加深)
- DP进阶(背包、树形、状压、数位、优化)
- 字符串(哈希、KMP)
- 图论基础(欧拉回路、最小生成树、最短路、拓扑、二分图、连通性、LCA)
- 数学进阶(排列组合、容斥、逆元、矩阵、高斯消元)
- 数据结构(ST表、堆、树状数组、线段树、Trie、并查集、平衡树)
- 计算几何基础
学习建议:
- 理解算法原理,注重模板的掌握与变形。
- 推荐练习平台:Codeforces、AtCoder、蓝桥杯真题。
3.3 大学A组 / 研究生组:高级挑战阶段
新增内容:
- 字符串高级(AC自动机、后缀数组/自动机、回文自动机)
- 图论高级(网络流、一般图匹配)
- 数学高级(生成函数、莫比乌斯反演、FFT)
- 数据结构高级(树链剖分、动态开点线段树、平衡树、可持久化、树套树、动态树)
学习建议:
- 需要有扎实的数学基础和算法推导能力。
- 多阅读论文、算法竞赛进阶指南。
- 推荐练习平台:LOJ、UOJ、POJ、ICPC/CCPC真题。
4.难度系数说明
- 系数1–3:基础题,主要考察语法和简单逻辑。
- 系数4–6:中等题,需要掌握常见算法模板。
- 系数7–8:难题,考察算法变形与组合应用。
- 系数9–10:极难题,通常涉及复杂数据结构或数学建模。
各组别难度向上兼容,A组题可能包含B组和C组的基础内容。
二. C++基础语法(上):从零开始的编程基石
适合参加蓝桥杯等算法竞赛的C++入门学习者,掌握这些语法知识是后续算法学习的必备基础
1.前言
在开始算法竞赛的征程前,我们首先要打好C++语法基础。无论是枚举、贪心还是动态规划,都需要扎实的语法功底作为支撑。本篇博客将带大家掌握C++最核心的基础语法知识,包括开发环境搭建、第一个程序、数据类型、输入输出、条件判断与循环等基础内容。
2.开发环境搭建 - DevC++的安装与使用
2.1 为什么选择DevC++?
DevC++是一款免费、轻量级的C/C++集成开发环境(IDE),特别适合初学者和竞赛选手。它使用GCC作为编译器,安装简单,操作便捷,很多学校的机房和竞赛场合都使用它。
2.2 安装步骤
- 下载安装包:可以从SourceForge下载Orwell Dev-C++ 5.11版本
- 以管理员权限运行:右键点击安装包,选择"以管理员身份运行"
- 选择语言:建议选择"简体中文"
- 同意协议:点击"I Agree"
- 选择组件:默认选项即可,直接点击Next
- 选择安装路径:可以自定义安装位置,建议不要包含中文路径
- 完成安装:勾选"运行Dev-C++ 5.11",点击Finish
2.3 首次启动配置
第一次打开DevC++时,会提示选择语言,选择"简体中文/Chinese"即可。
2.4 编写第一个程序
方式一:新建源代码
- 点击"文件"→"新建"→"源代码"
- 编写代码后按Ctrl+S保存,文件名以
.cpp结尾 - 按F11编译运行
方式二:新建项目
- 适合多文件组织
- 点击"文件"→"新建"→"项目"
- 选择"Console Application",C++项目
- 保存项目后,可以在项目中添加多个源文件
2.5 常用快捷键
| 功能 | 快捷键 |
|---|---|
| 编译 | F9 |
| 运行 | F10 |
| 编译+运行 | F11 |
| 调试 | F5 |
| 下一步调试 | F7 |
| 单步进入函数 | F8 |
2.6 调试功能
调试是排查程序错误的重要手段:
- 在行号处点击设置断点
- 点击调试按钮或按F5开始调试
- 添加变量查看,监控变量变化
- 使用F7单步执行,F8进入函数内部
3、第一个C++程序
3.1 基础程序框架
#include <iostream> // 头文件
using namespace std; // 使用std命名空间
int main() // 主函数,程序入口
{
cout << "Hello World!" << endl; // 输出语句
return 0; // 程序正常结束
}
3.2 main函数详解
- main函数是程序的入口,程序从main函数开始执行
int main()表示main函数执行结束后返回一个整型值return 0;表示程序正常结束,与前面的int呼应- 一个项目中只能有一个main函数
3.3 输入输出流 - cin和cout
#include <iostream>
using namespace std;
int main()
{
int num;
cin >> num; // 输入一个整数
cout << num << endl; // 输出这个整数,endl表示换行
return 0;
}
特点:
- cin和cout能自动识别变量类型,不需要像scanf/printf那样手动控制格式
<<是流插入运算符,与cout配合使用>>是流提取运算符,与cin配合使用endl的作用是换行并刷新缓冲区
3.4 命名空间
命名空间用于避免命名冲突。std是C++标准库的命名空间:
// 方式一:使用using namespace std;
#include <iostream>
using namespace std;
// 方式二:使用std::前缀
#include <iostream>
int main()
{
std::cout << "Hello" << std::endl;
return 0;
}
竞赛中常用方式一,写起来更快捷。
3.5 注释
// 这是单行注释
/*
这是多行注释
可以写多行内容
*/
快捷键:
- DevC++中:Ctrl + / 注释/取消注释
- VS中:Ctrl+K+C注释,Ctrl+K+U取消注释
4、数据类型
4.1 基本数据类型
| 类型 | 关键字 | 说明 |
|---|---|---|
| 字符型 | char | 存储单个字符 |
| 短整型 | short | 较短的整数 |
| 整型 | int | 常用整数类型 |
| 长整型 | long | 较长的整数 |
| 长长整型 | long long | 更长的整数 |
| 单精度浮点型 | float | 小数(精度较低) |
| 双精度浮点型 | double | 小数(精度较高) |
| 布尔型 | bool | true或false |
4.2 ASCII码表要点
- 大写字母AZ:6590
- 小写字母az:97122
- 数字字符09:4857
- 大小写字母ASCII码差值:32
- 换行符
\n:10
4.3 signed与unsigned
signed:有符号,可表示正负数(int默认就是signed)unsigned:无符号,只能表示0和正整数
unsigned int a; // 无符号整型
signed int b; // 有符号整型,等价于int b;
4.4 数据类型长度 - sizeof
cout << sizeof(int) << endl; // 4字节
cout << sizeof(long long) << endl; // 8字节
cout << sizeof(double) << endl; // 8字节
4.5 数据范围
| 类型 | 范围 | 数量级 |
|---|---|---|
| int | -21亿~21亿 | 10^9 |
| unsigned int | 0~42亿 | 4×10^9 |
| long long | -9.2×1018~9.2×1018 | 10^18 |
重要提示:做题时一定要注意数据范围,选择合适的数据类型。经典名言:“十年OI一场空,不开long long见祖宗”
4.6 typedef - 类型重命名
typedef long long ll; // 将long long重命名为ll
typedef unsigned int uint; // 将unsigned int重命名为uint
ll a = 10000000000; // 等价于 long long a = 10000000000;
5.变量和常量
5.1 变量创建
int age; // 创建变量
int score = 100; // 创建并初始化
5.2 变量命名规则
- 只能由字母、数字、下划线组成
- 必须以字母或下划线开头
- 不能使用关键字(如int、if等)
- 区分大小写
5.3 全局变量与局部变量
int global = 100; // 全局变量,在大括号外定义
int main()
{
int local = 10; // 局部变量,在大括号内定义
cout << local << endl;
cout << global << endl;
return 0;
}
重要区别:
- 全局变量默认初始化为0
- 局部变量不初始化则值是随机的(必须初始化后再使用)
竞赛技巧:竞赛中常用全局变量,因为自动初始化为0,且随处可用,避免传参麻烦。
5.4 常量
字面常量:
100 // 整型常量
'a' // 字符常量
3.14 // 浮点型常量
#define定义常量:
#define PI 3.14159
#define MAX 100
const定义常量(推荐):
const double PI = 3.14159;
const int MAX_N = 1000;
const定义的常量有具体类型,更严谨。
6. 操作符
6.1 算术操作符
| 操作符 | 功能 | 示例 |
|---|---|---|
| + | 加法 | a + b |
| - | 减法 | a - b |
| * | 乘法 | a * b |
| / | 除法(整数除法取整) | a / b |
| % | 取模(取余数) | a % b |
注意事项:
- 除数不能为0
%操作符只能用于整型- 负数取模结果的正负号由第一个操作数决定
6.2 浮点数除法
float x = 6 / 4; // 结果为1.0(整数除法)
float y = 6.0 / 4; // 结果为1.5(浮点数除法)
6.3 赋值操作符
int a = 10; // 初始化
a = 20; // 赋值
// 复合赋值符
a += 5; // 等价于 a = a + 5
a -= 3; // 等价于 a = a - 3
a *= 2; // 等价于 a = a * 2
a /= 4; // 等价于 a = a / 4
a %= 3; // 等价于 a = a % 3
6.4 类型转换
隐式类型转换:
int a = 3.14; // a = 3(double转int,截断小数)
double b = 10; // b = 10.0(int转double)
强制类型转换:
double d = 3.14;
int a = (int)d; // a = 3
char c = 'A';
cout << (int)c; // 输出65(字符的ASCII码)
6.5 单目操作符 - ++和–
int a = 10;
int b = ++a; // 前置++:先自增,后使用(a=11, b=11)
int c = a--; // 后置--:先使用,后自减(c=11, a=10)
7.输入输出进阶
7.1 getchar和putchar
#include <cstdio>
int main()
{
int ch = getchar(); // 读取一个字符
putchar(ch); // 输出这个字符
return 0;
}
特点:
- getchar不会忽略空白字符
- 读取失败返回EOF(-1)
- 在输入前按Ctrl+Z可模拟读取失败
7.2 printf格式化输出
基本用法:
printf("Hello World\n");
printf("There are %d apples\n", 3);
常用占位符:
| 占位符 | 含义 |
|---|---|
| %d | 十进制整数 |
| %lld | long long整数 |
| %f | 浮点数 |
| %c | 字符 |
| %s | 字符串 |
| %x | 十六进制整数 |
格式化控制:
printf("%5d\n", 123); // 宽度为5,右对齐:" 123"
printf("%-5d\n", 123); // 左对齐:"123 "
printf("%6.2f\n", 3.14); // 总宽度6,小数点后2位:" 3.14"
7.3 scanf格式化输入
基本用法:
int a;
scanf("%d", &a); // 注意&符号,取地址
int x, y;
scanf("%d%d", &x, &y); // 连续输入
重要特点:
- scanf处理数值占位符时会自动过滤空白字符(空格、制表符、换行符)
- 但
%c不会忽略空白字符,需要用" %c"的形式跳过空白
scanf返回值:
- 返回成功读取的变量个数
- 读取失败返回0
- 遇到文件结尾返回EOF(-1)
int r = scanf("%d%d", &a, &b);
if (r == 2) {
// 成功读取两个数
}
7.4 带空格的字符串输入
方法1:fgets
char str[100];
fgets(str, sizeof(str), stdin);
方法2:scanf特殊格式
char str[100];
scanf("%[^\n]s", str); // 读取直到遇到换行符
方法3:getline(string类型)
string s;
getline(cin, s); // 读取一行,包含空格
8. 条件判断
8.1 if语句
if (条件) {
// 条件为真时执行
}
8.2 if-else语句
if (条件) {
// 条件为真时执行
} else {
// 条件为假时执行
}
8.3 else if
if (条件1) {
// 条件1为真
} else if (条件2) {
// 条件2为真
} else {
// 都不满足
}
8.4 嵌套if
if (条件1) {
if (条件2) {
// 条件1和条件2都为真
}
}
8.5 悬空else问题
if (a == 1)
if (b == 2)
cout << "hehe";
else
cout << "haha"; // 这个else与第二个if匹配,而不是第一个
解决方法:使用大括号明确逻辑
9. 关系操作符
| 操作符 | 含义 |
|---|---|
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| == | 等于 |
| != | 不等于 |
注意事项:
- 不要将
==写成=(赋值) - 不要连续使用,如
a < b < c,应写成a < b && b < c - 浮点数比较要用误差范围:
fabs(a - b) < 1e-9
总结
上篇小结:
至此,我们已经掌握了C++的基础语法:开发环境、数据类型、变量常量、操作符、输入输出、条件判断和循环结构。这些是编写任何程序的基础,也是后续学习数组、字符串、函数和算法的前提。
在下篇中,我们将继续学习:
- 数组(一维数组、二维数组、字符数组)
- string字符串类型
- 函数与递归
- 位运算
- 结构体与类
请确保熟练掌握本篇内容后再进入下篇的学习。加油!感谢各位大佬的观看!
【练习题推荐】
- 洛谷:P1001 A+B Problem
- 洛谷:P5710 【深基3.例2】数的性质
- 洛谷:P5715 【深基3.例8】三位数排序
- 洛谷:P5720 【深基4.例4】一尺之棰
- 洛谷:P5721 【深基4.例6】数字直角三角形
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2504_93131538/article/details/158511396



