刷算法题之前,先把最基础的四样东西搞清楚:运算符号、判断、循环、数组。这篇文章不讲花活,就按做题的思路过一遍。
运算符号
算术运算
加减乘除大家都认识,算法竞赛里多几个要注意的:
int a = 7, b = 2;a + b; // 9a - b; // 5a * b; // 14a / b; // 3,注意!整数除以整数结果是整数,小数部分直接丢掉a % b; // 1,取余数重点:
a / b在两边都是整数时是整除,7/2 是 3 不是 3.5。想要小数,至少一边写成浮点,比如7.0 / 2。%是取余数,判断奇偶、判断能不能整除都靠它(a % 2 == 0就是偶数)。- 除以 0 是运行时错误,做题时要小心。
比较运算
结果是 true(真)或 false(假):
a == b; // 相等a != b; // 不相等a > b; // 大于a < b; // 小于a >= b; // 大于等于a <= b; // 小于等于注意是 == 判断相等,一个 = 是赋值。这是新手最常写错的地方,在 if 里写 if (a = b) 编译器只会警告,但逻辑完全错了。
逻辑运算
把多个条件拼起来:
a > 0 && a < 10; // 与:两个都成立才为真a < 0 || a > 10; // 或:有一个成立就为真!(a > 0); // 非:取反&& 有个特性叫短路:前面不成立了,后面的根本不会执行,有些题目会利用这个特性来避免越界。
自增自减
i++; // i = i + 1i--; // i = i - 1++i; // 先加再用i++; // 先用再加竞赛里一般就当作 i = i + 1 用,写循环计数器时到处都是。
赋值运算
a += 3; // a = a + 3a -= 3; // a = a - 3a *= 2; // a = a * 2a /= 2; // a = a / 2a %= 3; // a = a % 3写成缩略形式更短,也能减少手误。
判断:if / else if / else
程序不是一条道走到黑的,需要根据条件走不同分支:
if (score >= 90) { cout << "优秀" << endl;} else if (score >= 60) { cout << "及格" << endl;} else { cout << "不及格" << endl;}几个注意点:
- 从上往下匹配,命中一个就结束,后面的
else if不再看。所以条件的顺序很重要,从严格到宽松写。 - 单个语句时可以省略大括号,但建议永远带上,不然加代码容易出 bug。
switch也是判断的一种,适合”值固定、分支多”的情况,比一串else if干净:
switch (day) { case 1: cout << "周一"; break; case 2: cout << "周二"; break; default: cout << "其他"; break;}别忘写 break,不然会”穿透”到下一个 case。
循环:for / while
重复做一件事就用循环。
for 循环
最常见,尤其是”做 N 次”的题目:
for (int i = 0; i < n; i++) { // 重复执行 n 次}三个部分:初始化、条件、步进。i 从 0 开始、小于 n,这是 C++ 数组下标从 0 开始配套的习惯写法,背下来就行。
while 循环
不知道要循环几次、只知道什么时候停:
int x = n;while (x > 0) { x /= 2; // 每次减半}do-while
先执行一次再判断,至少会跑一次。竞赛里用得少,但偶尔有奇效。
break 和 continue
for (int i = 0; i < n; i++) { if (条件A) break; // 直接跳出整个循环 if (条件B) continue; // 跳过本次,进入下一次}break 是”不干了,走人”,continue 是”这次算了,下一轮继续”。
数组
数组就是一排连续的小格子,每个格子存一个值,通过下标访问。
定义和访问
int a[5]; // 定义 5 个 int,下标 0~4int b[5] = {1, 2, 3, 4, 5}; // 定义并初始化
a[0] = 10; // 往第一个格子里放值cout << a[0]; // 取出第一个格子的值下标从 0 开始,所以长度 5 的数组,合法下标是 0 到 4。访问 a[5] 就是越界了——编译器不一定报错,但会访问到别人的内存,轻则结果诡异,重则段错误崩溃。做题时这是最常见的坑之一。
遍历数组
配合循环把每个格子过一遍:
int sum = 0;for (int i = 0; i < n; i++) { sum += a[i]; // 累加所有元素}求最大、最小、求和、统计个数,全都是这个模板,只是循环体里换一下操作。
二维数组
二维数组就是”表格”,第一维是行、第二维是列:
int grid[3][4]; // 3 行 4 列
for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { // 两层循环遍历每个格子 }}越界与大小
- 数组开多大要提前想好。局部数组太大(比如几十万以上)可能爆栈,竞赛里经常把大数组放到全局,或者用
vector。 vector是动态数组,长度可以变,vector<int> v(n)、v.push_back(x),比裸数组灵活,竞赛里也很常用。
串起来的套路
做题时这四个东西基本是成套出现的:
int n;cin >> n;int a[105];for (int i = 0; i < n; i++) cin >> a[i]; // 读入
int cnt = 0;for (int i = 0; i < n; i++) { if (a[i] % 2 == 0) cnt++; // 判断 + 循环 + 数组}cout << cnt << endl;读入一组数 → 用循环遍历 → 用判断筛选 → 累加或统计,就是一道入门题的全部骨架。
总结
- 运算符号:加减乘除取余比较逻辑,重点记住整除、取余、
==vs=。 - 判断:
if / else if / else从上往下匹配,条件顺序从严格到宽松。 - 循环:
for固定次数,while看条件,break退出、continue跳过。 - 数组:下标从 0 开始,遍历靠循环,防越界。
先把这些写熟,再去刷题,后面的数据结构都是在这四样东西上长出来的。加油!
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时