1.保护式读取数据语句if (scanf("%d", &n) != 1) return 0;
这个语句的作用就是在int main之后读取数据的时候能够避免一些消耗运算时间的情况。用通俗易懂的话来说就是:如果在这次读取中,scanf 成功拿到的数字数量不等于1(没拿到,或者数据结束了),那说明后面没法玩了,主程序立刻return 0(直接结束程序)!"
下面用一道例题来表示这个语句
cpp
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main()
{
int N = 0;
if (scanf("%d", &N) != 1) return 0;
char A[100];
int ans = 0;
for (int i = 0; i < N; i++)
{
scanf("%s", A);
int len = strlen(A);
bool is_super = true;
for (int j = 1; j < len; j++)
{
if (A[j] != A[0])
{
is_super = false;
break;
}
}
if (is_super)
{
ans++;
}
}
printf("%d\n", ans);
return 0;
}
这个语句在这段代码里面的作用是:无论后面输入多少个字符串,只要不是1个整数,直接return 0
2.bool语句 bool
首先bool的本质就是非黑即白,只有两种情况,要么是对的,要么是错的。只有true 和 false两种情况。就是有的时候不好想出来,在考场上面容易忘记。从一道经典的判断素数的题目来显示bool的用法
cpp
#include <stdio.h>
#include <stdbool.h>
bool is_prime(int num)
{
if (num <= 1) return false;
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
int main()
{
int target = 0;
// 咱们刚学的防弹衣穿好!
if (scanf("%d", &target) != 1) return 0;
if (is_prime(target))
{
printf("%d 是素数\n", target);
}
else
{
printf("%d 不是素数\n", target);
}
return 0;
}
这个代码里面的bool语法可以避免在main主函数里面写很多代码,导致混乱。比如很多时候想不起来使用bool,就会使用int true = 0; int false = 0;然后在main函数里面写很多,bool就可以解决这个问题。
3.整数向上取整公式: (a + b - 1) / b
这个公式挺微妙的,当时做到这个思路的题目的时候,根本想不到还能这么写。当时只是一直在想着怎么样使用for循环来做这道题目,结果一个公式就解决了。
cpp
#include <stdio.h>
int main()
{
int N = 0;
int M = 0;
if (scanf("%d %d", &N, &M) != 2) return 0;
int boats = (N + M - 1) / M;
printf("总共有 %d 人,每条船坐 %d 人\n", N, M);
printf("最少需要租 %d 条船\n", boats);
return 0;
}
4.DFS
因为人类的大脑习惯了 for 循环那种"从左到右,做完拉倒"的线性思维。 但是 DFS 是折叠的思维。那个 dfs(step + 1) 程序运行到这里,会瞬间跳进另一个线程去执行,直到那个线程彻底结束(return),才会回到你当前这行代码的下一行(也就是执行 st[i] = false 撤销操作)。
cpp
void dfs(int step) // step:当前走到第几步了(或填第几个盒子)
{
if (到达了目标状态 / 盒子填满了)
{
打印结果或者统计数量;
return;
}
for (int i = 1; i <= 所有选项的数量; i++)
{
if (这个选项合法 && 没有被占用)
{
path[step] = i;
st[i] = true;
dfs(step + 1);
st[i] = false;
}
}
}