信竞 非常全面的知识点详解(涵盖...

物理
信竞 非常全面的知识点详解(涵盖C++、数据结构、算法)

用户头像
bits/stdc++.h 更新于2026-8-15 06:20:56
$\color{green}{\Huge{目录}}$
$\color{orange}{\Huge{第一章 C++语法基础}}$
1.程序基本结构
2.常量与变量及数学运算
3.输入输出流
4.指针和地址与输入输出函数
5.输入输出进阶与进制转化
6.数据类型及其转化
$\color{orange}{\Huge{第二章 C++分支结构与循环结构}}$
7.if-else if-else语句
8.switch-case-default语句
9.for循环
10.while循环和do-while循环
11.循环控制与循环嵌套
$\color{orange}{\Huge{第三章 线性数据结构基础}}$
12.数组
13.栈和队列
14.内存计算
$\color{orange}{\Huge{第四章 C++语法进阶}}$
15.逻辑运算与运算律
16.位运算
17.运算符优先级
18.库函数与cmath
19.自定义函数基础
20.自定义函数进阶与内联函数
21.流同步和缓冲区
22.结构体
$\color{orange}{\Huge{第五章 简单排序算法}}$
23.选择排序
24.冒泡排序
25.计数排序
$\color{orange}{\Huge{第六章 数据结构进阶与STL初步}}$
26.二维数组与多维数组
27.vector
28.stack与queue
29.list
30.priority_queue
31.deque
$\color{orange}{\Huge{第七章 更多的基础算法}}$
32.时间复杂度
33.贪心算法
34.前缀和
35.前缀和进阶
36.差分
37.差分进阶
38.二分
39.实数二分
40.递推
41.递归
42.归并排序
43.快速排序
44.sort与自定义排序
$\color{orange}{\Huge{第八章 数论算法}}$
45.最大公因数与最小公倍数
46.模运算性质及防负数取模
47.质数判断
48.算术基本定理
$\color{orange}{\Huge{第九章 树形数据结构基础}}$
49.树的定义及相关概念
50.树的深度优先遍历与广度优先遍历
51.二叉树的先中后序遍历
52.表达式
53.表达式树
$\color{orange}{\Huge{第十章 搜索算法基础}}$
54.深度优先搜索
55.广度优先搜索
56.记忆化搜索
$\color{orange}{\Huge{第十一章 枚举算法}}$
57.循环枚举及其优化
58.子集枚举
59.排列枚举
$\color{orange}{\Huge{第十二章 基于二进制的一些算法}}$
60.快速幂
61.倍增与ST表
$\color{orange}{\Huge{第十三章 其他技巧}}$
62.和式的处理技巧
63.离散化
64.预处理
65.空间换时间
$\color{orange}{\Huge{第十四章 C++语法再进阶与STL进阶}}$
66.类
67.作用域解析
68.重载运算符
69.upper_bound和lower_bound
70.max_element和min_element
71.迭代器
72.自动类型匹配
73.set与unordered_set
74.map与unordered_map
75.宏定义与万能头文件
$\color{orange}{\Huge{第十五章 树相关算法}}$
77.最近公共祖先
78.树上差分
79.DFS序
$\color{orange}{\Huge{第十六章 DP初步}}$
80.DP基本概念
81.经典例题之最大不邻项和
82.经典例题之最长上升子序列
83.经典例题之最长公共子序列
84.01背包初步
85.01背包优化
86.分组背包
87.完全背包
$\color{orange}{\Huge{第十七章 图初步}}$
88.图的定义及相关概念
89.图的遍历
90.拓扑排序与DAG的判定
91.连通块与泛洪算法
$\color{orange}{\Huge{第十八章 高级数据结构初步}}$
92.树状数组
93.线段树之建树与单点修改
94.线段树之区间查询
95.线段树之懒标记与区间修改
96.并查集
$\color{orange}{\Huge{第十九章 树进阶}}$
97.DFS序进阶
98.LCA进阶
$\color{orange}{\Huge{第二十章 图论算法基础}}$
99.最短路的松弛操作
100.Dijkstra算法
101.Dijkstra算法的优化
102.Bellman-Ford算法
103.SPFA算法
104.Floyd算法
105.Kruskal算法
$\color{orange}{\Huge{第二十一章 DP进阶}}$
106.树形DP
107.状压DP之常用位运算操作
108.哈密顿路径
$\color{orange}{\Huge{第二十二章 组合数学相关算法与数论进阶}}$
109.递推求组合数
110.直接求组合数
111.递推求逆元
112.直接求逆元
113.埃拉托色尼筛法
114.欧拉线性筛法
115.扩展欧几里德算法
$\Huge{\color{red}{先开个坑 之后会逐渐更新}}$
收起
56
52
共27条回复
时间正序
用户头像
bits/stdc++.h
1月前
$\Huge{\color{red}{声明:在评论区更新,防止吞\LaTeX}}$
用户头像
bits/stdc++.h
1月前

1.程序基本结构

在C++程序中,我们使用的绝大多数指令都被封装在一个一个的头文件中,要想调用这些指令,我们得先引入他们所在的头文件,语法为

#include <头文件名称>

然后,我们要写上这样一行

using namespace std;

它的作用以后会讲

另外,C++程序有一个入口点,程序从这里开始运行,这就是主函数 ,语法为

int main (){

     代码

}

最后在主函数最后一行写上return 0;这是程序结束的标志,然而作为最后一行也可不写它,因为程序执行完主函数会自动结束。

最终基本模板如下

#include <头文件>

using namespace std;

int main (){


    return 0;

}

4条评论
用户头像
熊大
1月前

c++23支持模块导入,比如

import std;

auto main -> int{

std::cout << 325799;

return 0;

}

用户头像
Rinrir 回复 熊大
1月前

这种东西最好不要用。因为正规的考试(比如CSP)只能用C++14,不支持C++23,,,

不过平时可以用吧,我也不确定。。。

用户头像
Severus Jobs
1月前

头文件可以直接用这个@bits/stdc++.h(万能头文件)

用户头像
喵呜不白猫 回复 Severus Jobs
1月前

万能头的计算时间长,容易

用户头像
bits/stdc++.h
1月前

2.常量与变量及数学运算

常量,顾名思义,就是恒定不变的量。

比如,我们有一个数998244353,我们要经常使用这个量,那么每次用它的时候都要在程序里写上998244353这个量,非常麻烦。但如果我们用一个别的东西代替他,比如字母p,那么用它的时候写一个p就行,这就是定义了p这个常量,其值为998244353,定义常量语法如下:

const 数据类型 常量名称 = 值;

存储整数,数据类型常用int,取值范围为$-2^{31}到2^{31}-1$,即-2147483648到2147483647

举个例子(栗子 : 我恐高,别举我)

const int p = 998244353;

这就实现了开头那个例子

有一点发现了吗?结尾有分号!看看之前的using namespace std;也是这么写的。其实,一般而言每句代码末尾都要加上他,但也有例外,比如头文件引入。还有一些也不用加分号,以后再讲。

其实const还有一个写法是constexpr,简单了解即可。作者本人倾向于写后者。

变量呢?Very easy! 把常量修饰符去掉即可。语法为

数据类型 变量名 = 值;

这个值不用非得一开始就赋,可以只定义不赋值。语法为

数据类型 变量名;

也可以定义多个变量,中间用逗号隔开,前提是类型相同。

🌰:

int a = 114514, mod, p = 123;

后期可以对变量的值进行修改。语法为

变量名 = 新的值;

运算很简单,变量、常量、数值三者间可以随意搭配进行计算。

加法减法和数学中的写法一样,乘法为*,除法为/,这里的除法默认向下取整。

🌰:

constexpr int A = 3;

int b;

b = A / 2;

此时b值为1

这一切都要在主函数中写。其实也可以在主函数外写,以后细讲。

最后强调:

变量名常量名千万别乱取!命名规则:

  1. 只能以数字,字母,下划线组成
  2. 不得以数字开头
  3. 不得用C++自带的指令
综合练习,以下代码运行完后,变量a的值是?

int main (){

    int a = 5;

    constexpr int c = 3;

    a = a * 5 / c;

    return 0;

}

加餐;

a = a + b;等价于a += b;

其余三者同理。

a = a + 1;等价于a++;或++a;区别以后讲。

减法同理。


用户头像
bits/stdc++.h
1月前
3.输入输出流

头文件:iostream
下面开始介绍。
输出一个东西,要用cout指令,他的语法是
cout << 内容;
内容是啥都行,可以是字符串(用双引号包起来),也可以是字符(用单引号包起来),也可以是数字,也可以是常量和变量,也可以是换行(写为'\n'或endl,区别比较高深,以后会讲)。如果不换行的话,所有的内容都会挤在一起,所以可以选择加入空格来区分他们。
若要输出多个内容的话,多写几个<<即可。
🌰:
cout << 114 << 514 << endl << 2 << ' ' << 7;
输出结果为
114514
2 7
输入用cin。为啥要先讲变量再讲输入呢?这么问答案其实已经泄漏出来了。输入数据要使用变量进行存储,否则数据就丢了。
语法为
cin >> 变量;
输入多个数据时,处理逻辑与cout相同。不过输入数据要用空格或换行隔开,否则会被当成一个数据处理。
🌰:
输入 :
14159 2653
代码:
#include <iostream>
using namespace std;
int main(){
    int a,b;
    cin >> a >> b;
    cout << a << b * 10 + 5;
    return 0;
}
输出:
1415926535

1条评论
用户头像
熊大
1月前
为防止卡常,当输入数据量较大时需要加速,常使用快读,scanf,关闭流同步等方式
bro我认为你可以在最后放几道题目讲讲
3条评论
用户头像
bits/stdc++.h
1月前

OK,从第五节开始放题

用户头像
沐辛和雪橇犬『MT19937』 回复 bits/stdc++.h
1月前
em...其实我觉得这个贴很全了,更完的话不容易,而且代码也不好打,实在不行建议用图
用户头像
bits/stdc++.h 回复 沐辛和雪橇犬『MT19937』
1月前

从第5节开始我就开始用图。

用户头像
bits/stdc++.h
1月前

4.指针和地址与输入输出函数

地址指的是计算机当中变量或常量或其他东西(如以后学的数组)的存储位置。

指针存储的就是他们的地址。

如果我们要定义一个指针,他存储一个某类型变量的地址,应该这样写

数据类型* 指针名 = &变量名;

这里有两个符号,介绍一下:

*在此处告诉计算机,新定义的这个东西是一个指针,不是普通的变量。

&叫做取地址运算符,用于获取他后面跟着的那个东西的地址。

比如我们有一个变量a,这样写

int* p = &a;

这样,p中就存储了a的地址。

输出p,就可以看到a的地址了。

地址一般长这样:


IMG_20260809_114507_1.jpg

这是我电脑上运行的结果。

下一节就会讲他是什么意思,以及为什么以0x开头。

若我们想要获取指针指着的那个变量它的值,就要写*p,这里的*是解引用运算符

🌰:

int a = 5;

int* p = &a;

cout << *p;

输出结果为5

当然,指针不用非得定义时就指向变量,只写int* p;也可以,不过最保险最正式的写法是int *p = nullptr;

nullptr叫做空指针,也可写NULL,建议写前者。

指针可以改变指向的变量。语法为

指针名 = 新变量的地址;

如p = &b;

这样p就指向了b。


输入输出函数很简单。

头文件:cstdio

输入为scanf("格式控制符",变量地址);

对于int而言,格式控制符是%d

输入多个数据就多写几个%d

例如scanf("%d%d", &a, &b);

输出为printf("输出内容",变量);

输出内容可以加格式控制符,变量可以不加。但加了%d之类的数据类型控制符必须跟上变量。

换行只能写'\n'

🌰:

已知a = 5;b = 4;

printf("happy %d\n%d", a, b);

输出为

happy 5

4

3条评论
用户头像
Rinrir
1月前

啊吧啊吧(码完字后一退出就没了QAQ

我能讲一讲endl (endline)和'\n'的区别吗QWQ

好像\n的时间更快一些

适用于:大数据(比如多组数据),这时输出用\n就比用endl快一些

(遇到一些卡常的就可以用

(亲测,用endl超时改为\n过了

(本人习惯用\n

用户头像
bits/stdc++.h 回复 Rinrir
1月前

确实。实际上,endl = \n + 刷新缓冲区,所以endl更慢

用户头像
沐辛和雪橇犬『MT19937』 回复 Rinrir
1月前

首先呢,endl和\n最大的区别就是时间,而且\n是一个转义字符,这就导致不会刷新输出缓冲区,而endl会,相当于多用了时间,所以\n快,一般的,都不用endl

用户头像
bits/stdc++.h
1月前
5.输入输出进阶与进制转化
输入输出的方法除了之前讲过的四种之外,还有一些特殊的输入输出方法。
putchar()指令用于输出一个字符,puts()用于输出字符串。
用法如下图

IMG_20260809_162946_1.jpg

输出:

a

abc

一般地,我们用string类型的变量存储一个字符串。
例如string s = "happy";
对于已经讲过的输入而言,如果碰到了空格,就会被截断。
🌰:
一整行输入abcdefg hijklmn
如果只写一个cin >> s;的话,只会将abcdefg读入并存在s中,hijklmn是不会被存进去的。
但如果我们就是想存入一整行,这该怎么办呢?
答案是,使用getline指令。语法为
getline(cin,变量名);
注意:连空格也会被读进去!
图片如下:

IMG_20260809_163134_1.jpg

对应的输入和输出:

第一行为输入,第二行为输出。

IMG_20260809_163139_12.jpg

接下来我们来聊一聊进制转换。
十进制,我们整天都在用。
二进制,逢二进一。八进制,逢八进一。
十六进制当然就是逢十六进一啦!
but,阿拉伯数字无法用一个数码表示十到十五的数字啊!
〘系统提示:英文字母被迫营业〙
我们用A表示10,B表示11,以此类推。
用小写字母也可以。(小写字母:终究没逃过……)
我们熟悉的是十进制,而计算机熟悉的是二进制。
十进制转二进制咋转呢?不断除以2,取余数,倒序写出来,商为0为止。
🌰:
把十进制数11转化为二进制数。
$11\div 2=5......1$
$5\div 2=2......1$
$2\div 2=1......0$
$1\div 2=0......1$
把余数倒着写,答案就是1011
对于十进制其他进制同理,这里注意转16进制可能会出现大于等于10的数,记得转化成字母。
如果是十进制小数呢?
对于整数部分,还是用刚刚那个办法就行。对于小数部分,要用的方法是乘基R取整法
每次都乘以基数,几进制基数就是几。取出整数部分写入答案,剩下的小数部分继续乘,小数部分乘完为止。
例如3.375转二进制
整数部分转换完是11。
小数部分:
0.375 × 2 = 0.75, 取出0
0.75 × 2 = 1.5,取出1
0.5 × 2 = 1,取出1,结束
正序写,及0.011
所以答案为11.011

其他进制转十进制呢?对于每一位,我们都要乘上他的位权,再相加。
位权是基数的幂次,从整数部分最低位(0次幂)起,往高位幂次逐级加一,往低位逐级减一。
🌰:二进制11.011转十进制
答案为$1 × 2^1 + 1 × 2^0 + 0 × 2^{-1} + 1 × 2^{-2} + 1 × 2^{-3}$ = 3.375

练习题:
1.把十进制数123转化为八进制
2.把二进制数101001转化为十六进制
3.十进制有限小数转化为二进制可能会出现无限小数吗?若有请举例,若没有请说明理由。
2条评论
用户头像
Rinrir
1月前

我一直用的万能头不太知道,字符串好像也要用一个头文件吧,,,

#include<string>好像是

最好还是用万能头,不然有一些东西只用iostream是会报错的。。。

用户头像
bits/stdc++.h 回复 Rinrir
1月前
呃。。。但是万能头被我放进后面另外一节里面了(见目录)。并且一上来就用万能头可能读者就会忘掉哪个函数在哪个头文件中,况且万能头文件只在竞赛里用的多,软件开发的话用的少,因为他会拖慢编译时间,且可移植性弱。
用户头像
bits/stdc++.h
1月前

6.数据类型及其转化

先了解一下常用数据类型

int之前讲过,在此不再赘述。

short:同样也是整数,存储范围-32768到32767

long long:依旧是整数,存储范围$-2^{63}到2^{63}-1$

float:小数(浮点数),准确名称是单精度浮点数,小数精度约6到7位有效数字

double:双精度浮点数,小数精度约15到17位有效数字

bool:布尔值,只有0(false)和1(true)两种取值,常被用于标记真假(例如是否被访问过,是否满足要求等)

char:字符。

string讲过,不再赘述。

这些数据之间是可以相互转化的。

整数转小数很好理解。

小数转整数呢?计算机是这样处理的:直接把小数部分干掉!

比如double型的3.1415926转化成int型就是3

那如果要四舍五入呢?答案是:先加0.5再转化,自己举几个数试一下就会发现原理。

你可能想不到的是,字符和整数也可以互相转化。

依靠的是ASCII码,其中'A'为65,'B'为66,以此类推。'a'为97,同样往后推,'0'为48,同理往后推。

至于转化的语法呢?

法一:强制类型转化

(目标类型)(被转化的式子)

法二:安全类型转化

static_cast<目标类型>(被转化的式子)

🌰:

IMG_20260809_194206_1.jpg

输出:

97

97


其实还有一种转化方式,叫做自动类型转化,比如int和double做运算时默认把int转double,结果为double

所以,直接两个整数相除,结果为整数,若先给被除数乘上一个1.0,让被除数变成double,这样计算结果也会变成double,例子如下:

IMG_20260809_163846_1.jpg

输出:

1

1.5

加餐:

类型修饰符,unsigned表示无符号,使用它可以使得数据类型值非负,正数部分上限比原先增大了原本负数部分的值域大小。

例:unsigned int


练习题:

『原创编程题』

题目描述:

给定一个大写英文字母,输出它是第几个字母。

输入格式:

一行,一个英文字母。

输出格式:

一行,一个整数,表示第几个字母。

内存限制:

时间限制:

数据范围:

对于输入的英文字母,保证合法。

5条评论
用户头像
Rinrir
1月前

冷知识(热知识:

整数和字符串也可以转化🤓

整数(int转化为字符串:to_string(很好理解吧。。。

字符串转化为整数:stoi(也很好理解吧,,,sting to int

字符串转化为long long:stll(好像是这个,不怎么用,string to long long

用户头像
Rinrir 回复 Rinrir
1月前

热知识×2:

当你想输出保留x位小数时,有两种方法:

1:printf

printf("%.xld", ans); (这里以ans为输出的答案,x为保留的位数

2:cout(有亿点长,耗时间,不太建议使用

cout << fixed << setprecision(x) << ans; (同上。

用户头像
熊大 回复 Rinrir
1月前

建议使用stoi的时候观察一下数据范围(超过int范围会直接报错),可以用try…catch的写法

用户头像
北宅_Tirpitz
24天前

大佬整理得很全面啊 把几种类型都放在一起了 但是关于文中提到的 强制类型转换 和 安全类型转换(static_cast)我想补充一个理解   对于数值类型转换两种写法其实都会直接截断小数部分 运行期上没有任何'安全'差别 static_cast更受推荐是因为编译期检查更严格但它并不做运行期检查 真正的安全类型转换应该是  dynamic_cast<目标>(表达式) 要求是目标为以下三种: Derived*  Derived& void* 然后表达示: 左值 泛左值 指针纯右值

用户头像
(流)星 回复 Rinrir
10天前

不应该是printf(“%.xf”,ans)吗然后输出小数点后x位

用户头像
bits/stdc++.h
1月前

7.if-else if-else语句

首先先讲一下关系运算符,他们成立返回真(true),不成立返回假(false)。

> 大于

< 小于

>= 大于等于

<= 小于等于

== 等于

!= 不等于

比如5 >= 4就为true,5 == 6就为false,很好理解。


if语句能根据条件是否成立而决定下一步做什么。

基本语法是:

if (条件){

    代码

}

条件别加分号!大括号后也别加分号!

如果条件成立,就执行大括号内的代码,不成立就跳过。

如果条件不成立,要执行某些代码,就写else

if (条件){

    条件成立时执行的代码

}

else{

    条件不成立时执行的代码

}

如果条件不成立还要再判断另一个条件,就用else if新增条件,在if条件不成立时就判断else if条件是否成立。

若多个else if存在,就挨个判断,一个成立,剩下的else if和else都跳过。

例如

IMG_20260810_165458_1.jpg

模拟一下程序执行过程。

若输入a为5,if中的条件成立,输出1,跳过else if和else,程序结束。

若输入a为0,if中条件不成立,看else if条件,成立,输出2,跳过else,程序结束。

若输入a为-1,if中的条件不成立,看else if,也不成立,执行else,输出3,程序结束。


当if ,else if,else以及后续要学的for,while语句大括号内只有一句代码,大括号可以省略不写,如下

IMG_20260810_165516_1.jpg


练习:

『原创编程题』

题目描述:

给定一个a (a∈Z),输出他的绝对值。

输入格式:

一行,一个整数。

输出格式:

一行,一个整数,表示a的绝对值。

时间限制:

无。

内存限制:

无。

数据范围:

题目保证$-2^{63} ≤ a ≤ 2^{63} - 1 且 a∈Z$

4条评论
用户头像
沐辛和雪橇犬『MT19937』
1月前

hem...我试试

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll n;

int main(){

    cin>>n;

    court<<abs(n);

    return 0;

}

用户头像
沐辛和雪橇犬『MT19937』
1月前

那我来补充一下,就是这个括号里永远是一个真/假的值,而在C++里,0是假,其他的都是真,所以写if(x)就可以过滤x=0的情况

用户头像
Rinrir
1月前

那我也来补充一下吧🤓

三目运算符:

适应于:if-else语句

用法:

平时:

If (x == 1) cout << “No“;

else cout << "Yes";

运用三目运算符:

cout << (x == 1 ? "No" : "Yes");

好处:压成一行,简单(?)

接下来讲解怎么用:

int x = (条件1,例如f == 1 ? 条件一对应的结果,例如1 : 条件二的结果,代表条件一不成立,例如-1);

分号和问号是必须要加的,不能调换位置或删除。

用户头像
沐辛和雪橇犬『MT19937』 回复 Rinrir
1月前

great,我正好不大会用田猛1.png

用户头像
bits/stdc++.h
1月前

8.switch-case-default语句

当有一个变量,他有不同的值,每一个值就对应一种结果,很容易想到if-else if-else语句。

还有另一种语句,专门用于处理这类问题,即本节内容。

先摆上语法:

switch (变量名){

    case 值1:语句1;break;

    case 值2:语句2;break;

    case 值3:语句3;break;

    default:语句;break;

}

当变量值为值1时执行语句1,变量值为值2时执行语句2,所有case以此类推。当所有case都没有匹配上,执行default的语句,当然,default也可以不写。

🌰:

IMG_20260810_165721_1.jpg

输入a,a值为1时输出"one",a值为2时输出"two",a值为3时输出"three",都不是输出"no"。


练习题:

编写代码,输入一个字符,用switch语句处理他,使得无论输入什么字符,输出总是'A'。

用户头像
bits/stdc++.h
1月前

9.for循环

循环,顾名思义就是重复地做一件事。

for循环的基础语法如下:

for (循环初始化;循环条件;循环迭代){

    循环体

}

循环初始化就是执行到for循环时,先执行初始化语句。

然后判断循环条件是否满足,若满足,就执行循环体(就是要重复执行的代码),然后进行循环迭代(一轮循环结束后对变量等进行修改)。接下来再判断循环条件是否满足,就是一直走刚刚所述的流程(不包括初始化),直到条件不满足为止。

比如要循环n次,就可以定义一个用于统计循环次数的变量i,从1开始,直到i > n为止,也就是循环需满足i <= n,每次循环完就把i加1,表示循环完的轮数增加了1。也就是说,初始化int i = 1,条件i <= n,迭代i++

即for (int i = 1;i <= n;i++)

由for循环的底层原理可知,在循环的时候,i的值是会不断改变的。像这样,在循环中的变量,称为循环变量。而循环变量的值也是可以像一般的变量一样输出的。🌰:

输出1到10之间所有整数

IMG_20260810_165900_1.jpg

其实for循环三个部分不一定都要写,甚至三个部分都不写(无限循环)。

比如for (int i = 1;i <= 10;)

再比如for (;i > 0;)


加餐(别噎着):

从初始值循环到终止值,循环变量每次都增减某个固定的常数,这种循环就是形如for (int i = 初始值;i 大小关系 终止值;i 增或减 常数)的循环,一开始的那个例子就是。在这种循环中,循环变量每次改变的值称为循环的步长

步长是可以改变的。比如,输出[1,n]之间所有的奇数,由于1本身是奇数,相邻两个奇数相差2,故可以这样写

IMG_20260810_170012_1.jpg

饭后甜点(小心血糖飙升):

有没有发现刚刚加餐里的那种循环,在步长为1和终止值大于初始值的时候,for循环和数学上的$\sum$求和很像?


小练习:

利用for循环求值$\sum_{i=1}^{10}i^2$

用户头像
bits/stdc++.h
1月前

10.while循环和do-while循环

while循环,可以理解成只有循环条件的for循环。基本语法为:

while (条件){

    循环体

}

当条件成立时,执行循环体。他等价于for (;条件;)。乍一看,这不有for循环就行了?搞出个while循环干啥?

代码要注重可读性,这在你写完代码后回头看的时候会体现出来。while循环是不是比他等价的for循环更美观?况且那种三个部分都有的for循环特别常见,写习惯了他们就不习惯这种缺两项的for循环。

while循环可以干啥呢?仔细看一看,只要同条件满足,就一直执行循环体。所以while循环可以被用来榨干某些东西。

先讲一讲模运算。符号为%,用于计算两个数相除的余数。

判断偶数的方法:当且仅当a % 2 == 0成立。等于1就是判断奇数,很好理解。

有了这一点,我们就可以榨干一个偶数的所有因子2。

🌰:给出一个数,若他是偶数,就不断地除以2,直到它是奇数,并输出最终剩下的数。参考代码:

IMG_20260810_170146_1.jpg


do-while循环先执行循环体,再根据条件来判断是否进入下一次循环。

语法:

do{

    循环体

}while(条件);

例如,给定一个数,不管他是啥,先除以2,向下取整,再榨干全部质因子2。代码:

IMG_20260810_170414_1.jpg


练习题:

『原创编程题』

题目描述:

给定一个数$a$,判断素因子$2$和$3$谁多,输出较多者的个数。

输入格式:

一行,一个数$a$。

输出格式:

一行,一个整数,含义如题目所述。

时间限制:

无。

内存限制:

无。

数据范围:

题目保证$a∈N^{*},a ≤ 10^5,6|a$

3条评论
用户头像
AIMEE11
1月前

防止评论太水我先打些稍微干点的:while内的条件判断和if内的是一样的,程序内会给表达式赋一个bool值,机制是如果非0即为1,也就是说while(1)和while(1111)的效果是一样的,都是死循环。while(1)是一个非常简单而且有效的卡机方法,不过目前ccf的评测机子貌似进化过了应该不会被卡。

因此,如果想要在本地测试时让循环一直持续并使用循环内判断的方式跳出,不建议用while(1),可以试着给一个变量赋较大值然后自减防止被卡。比如

unsigned ll cnt=1e20;

while(cnt--){……}


饺子醋来了:帖主用的IDE是不是小熊猫?很眼熟,好像是小熊猫的初始配色()由于vscode更新后又得重新配置太累人了所以我后面果断换成了小熊猫

用户头像
bits/stdc++.h 回复 AIMEE11
1月前

我用的是vs code

用户头像
AIMEE11 回复 bits/stdc++.h
1月前

哎哎这样吗,我个人比较喜欢vscode的浅色,没看出来