jiezhi(易)的c++知识库

易jiezhi 个人空间 lv114514

格式化输入输出

printf()
scanf()
格式化输入输出
%d :int
%c :char

%f :float

printf()

            原宽大比2大,则原数据原样输出  
设置输出内容宽度——|  
             |				原宽大比2小,则填充0输出  

修饰符:%02d
|
设置填充字符

换行符:\n

printf()和scanf()包含在cstdio文件中,所以必须在程序中先包含该文件

scanf() —— 按规定格式输入内容 —— scanf(“格式字符串”,数据1,数据2)
printf() —— 按规定格式输出内容

setw()函数

setw(n) —->设置输出内容所占的总宽度n
setfill(c) –>设置填充字符c

1
cout<<setw(5)<<18<<endl;

18 | 1 8| 输出内容宽度大于(设置的宽度)时,则原样输出

cout<<setw(5)<<18<<endl;
只对紧跟其后的内容

输出时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int h,m,s,s1;
cin>>s1;
h=s1/3600;
s1-=h*3600;
m=s1/60;
s1-=m*60;
s=s1;
cout<<setw(2)<<setfill('0')<<h<<":"<<setw(2)<<setfill('0')<<m<<":"<<setw(2)<<setfill('0')<<s;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int t;
cin>>t;
int h=t/60/60;
int m=t/60%60;
int s=t%60;
cout<<setw(2)<<setfill('0')<<h<<":";
cont<<setw(2)<<setfill('0')<<m<<":";
cout<<setw(2)<<setfill('0')<<s;
return 0;
}

简化形式

条件?条件成立执行语句1:条件不成立执行语句2

cout格式化输出float格式

1
#include <iomanip>
控制符 作用
fixed 保留小数点后n位数
setprecision(n) 保留小数点后n位数

fix—>安装、固定

precision—>精确度

1
2
3
float a=31.21;
cout<<fixed<<setprecision(1)<<a<<endl;
//两个控制符必须同时出现,前后顺序无所谓

setprecision设置原则:四舍五入

scanf、printf输出float

float占位符

占位符 说明
%d int
%c char
%f float
%g 去除浮点数float小数尾0
%lf 双精度float
%lg 去除双精度float double小数尾0

%f占位符默认输出6位小数,不够6位,则在小数后面补0

printf()实现float格式化输出

1
printf("%.1f",b);

%.nf 保留小数点后n位

双精度浮点型

有效数字和精度

有效数字:从一个数的左边第一个非0数字起,到末位数字止,所有的数字都是这个数的有效数字。

精度就是指有效数字的个数

float的精度

float类型精度7位有效数字

double数据类型

float 单精度浮点型(16位有效数字,精度高)

%lf 双精度占位符

字面常量(字面值)

将程序中的数字、字符、文本称为字面常量,也称为字面值

例如:0,1,18,3.14,4,8,’a’,”hello”等

double类型的3.14 转换成为float类型:3.14f

整数进行运算的结果还是整数

自动数据类型转换规则

转换规则:低精度->高精度

类型
char
int
float
double

数据储存到与其数据类型不一致的变量中,也会发生自动数据类型转换

总结规律

strcmp(s1,s1)

作用:对字符串s1,字符串s2的内容进行比较

结果>0|1,s1>s2

<0|-1,s1<s2

==0,s1==s2

string字符串

string是一种数据类型:字符串

string类型的变量可以储存字符串

空格输入

string变量输入带空格的字符串

语法格式:getline(cin,s)

length函数

string s=”1”

作用:用于计算字符串s的长度

语法格式:s.length()

函数

定义函数的语法格式

数据类型 函数名()

1
2
3
{
函数体
}

void 数据类型

常用四个系统函数

函数 说明
max(x,y) 找出两个最大值
min(x,y) 找出两个最小值
swap(x,y) 交换
sort() 排序

结构体

定义结构体的语法格式

struct 结构体名

{

数据类型1 变量名1;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <bits/stdc++.h>
using namespace std;
struct stu
{
int id;
string name;
double sc;
};
int main()
{
stu a={1,"yaya",98};
cout<<a.id<<endl<<a.name<<endl<<a.sc;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>
using namespace std;
struct stu
{
int id;
string name;
double sc;
};
int main()
{
stu a[4];
for(int i=1;i<=3;i++)
{
cin>>a[i].id>>a[i].name>>a[i].sc;
}
for(int i=1;i<=3;i++)
{
cout<<a[i].id<<endl<<a[i].name<<endl<<a[i].sc<<endl;
}

return 0;
}

数组进阶

列对称

垂直对称的两个元素,**列下标相加的结果等于n-1a[i][j]a[i][n-1-j]**垂直对称。

行对称

水平对称的两个元素,**行下标相加的结果等于n-1a[i][j]a[n-1-i][j]**水平对称

主对角线

主对角线上的元素下标:**i==j**

**a[i][j]a[j][i]**关于主对角线对称。

副对角线

副对角线上的元素下标:**i+j==n-1**

**a[i][j]a[n-1-j][n-1-i]**关于副对角线对称。

递推算法

从已知的**初始条件出发,依据递推关系,推出所求的结果,这种方法称为递推算法**

难题解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>
using namespace std;
int a[51]={},b[51];
int main()
{
int x,y,z;
//x+1------z+1 虫=上月虫的数量+前两个月卵的数量
// 卵=x个月虫的数量*y
//x月之前只有一对虫 0对卵
cin>>x>>y>>z;
for(int i=1;i<=x;i++)
{
a[i]=1;
}
for(int i=x+1;i<=z+1;i++)
{
a[i]=a[i-1]+b[i-2];
b[i]=a[i-x]*y;
}
printf("%d",a[z+1]);
return 0;
}

前缀和

前n项的和叫做前缀和

求前缀和数组

s[1]=a[1] (i=1)

s[i]=s[i-1]+a[i]

前缀和计算区间和

计算区间和L~R:s[R]-s[L-1]

差分

3 5 9 19 20 23 30

差分:**每一项前一项**。

第一项差分:3-0=**3 **

第1个数字的前1项默认为0

性质:对**差分数组前缀和,得到原数组**。

在计算机中有一种容器:

  1. 容器只有一个口进行数据的存取。

** 2.先存入的数据后取,后存入的数据先取。**

叫做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;
int a[6]={},top;
//进栈
void push(int x)
{
if(top<5)
{
a[++top]=x;
}
}
//出栈
void pop(){if(top>0) a[top--]=0;return;}
//获取栈顶
int getTop(){return a[top];}
//清空栈
void clear(){top=0;return;}
int main()
{


return 0;
}

指针

指针结构体

1
2
3
4
5
6
7
8
9
10
struct stu
{
int id;
string name;
double score;
};
stu a={1,"yaya",98.5};
//取结构体变量地址与普通变量相同
指针访问数据方式: 指针名->成员名
cout<<p->id<<endl = cout<<a.id<<endl;

指针实行变量交换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;
void fun(int *a,int *b)
{
int x=0;
x=*a;*a=*b,*b=x;
}
int main()
{
int a=5,b=6;
int *pa=&a,*pb=&b;
//变量a、b的交换
fun(pa,pb);
cout<<a<<" "<<b<<endl;
return 0;
}

搜索

深度优先搜索

这种**能深则深,不能深则退的方法,称之为深度优先搜索**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
char mp[25][25];
int vis[25][25],n,m,ans=0;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
void dfs(int x,int y)
{
for(int i=0;i<4;i++)
{
int fx=x+dx[i];
int fy=y+dy[i];
if(fx>=0&&fx<n&&fy>=0&&fy<m&&vis[fx][fy]==0&&mp[fx][fy]=='#')
{
vis[fx][fy]=1;
dfs(fx,fy);
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>mp[i][j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='w'&&vis[i][j]==0)
{
ans++;
vis[i][j]=1;
dfs(i,j);
}

}
}
cout<<ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <vector>
#include <iostream>
using namespace std;
void dfs(int node, const vector<vector<int>>& adj, vector<bool>& visited) {
visited[node] = true;
cout << node << " ";

for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
dfs(neighbor, adj, visited);
}
}
}
void startDFS(int startNode, const vector<vector<int>>& adj) {
int numNodes = adj.size();
vector<bool> visited(numNodes, false);

dfs(startNode, adj, visited);
}
int main() {
// 示例图的邻接表表示
vector<vector<int>> adj = {
{1},
{0, 2, 3},
{1, 4},
{1, 4},
{2, 3}
};

int startNode = 0;
cout << "DFS遍历顺序: ";
startDFS(startNode, adj);
cout << endl;

return 0;
}

广度优先搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
node a={1,1};
q.push(a);
vis[1][1]=1;
while(q.empty()!=1)
{
node f=q.front();
if(mp[f.x][f.y]==2)
{
cout<<"yes";
}
for(int i=0;i<4;i++)
{
int nx=f.x+dx[i];
int ny=f.y+dy[i];
if(nx>=1 && nx<=4 && ny>=1 && ny<=4 && mp[nx][ny]!=1 && vis[nx][ny]==0)
{
vis[nx][ny]=1;
node r={nx,ny};
q.push(r);
}
}
q.pop();
}


例题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
const int Z=200;
using namespace std;
struct X
{
int a,b,c;
};
int n,m,u,v,w,x,d[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
char g[Z][Z];
bool vis[Z][Z];
queue<X> q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>g[i][j];
if(g[i][j]=='S')
{
u=i;v=j;
}
if(g[i][j]=='T')
{
w=i;
x=j;
}
}
}
q.push({u,v,0});
vis[u][v]=1;
while(!q.empty())
{
X y=q.front();q.pop();
if(y.a==w&&y.b==x)
{
cout<<y.c;
return 0;
}
for(int i=0;i<4;i++)
{
int p=y.a+d[i][0],r=y.b+d[i][1];
if(p>0&&p<=n&&r>0&&r<=m&&g[p][r]!='#'&&!vis[p][r])
{
vis[p][r]=1;
q.push({p,r,y.c+1});
}
}
}
return 0;
}

排序

冒泡排序

冒泡排序原理冒泡排序是一种简单的排序算法,通过重复遍历数组,比较相邻元素并交换顺序不对的元素,将较大的元素逐渐“浮”到数组末尾。具体步骤如下:1遍历数组,比较每一对相邻元素,交换顺序不对的元素。2每次遍历将最大的未排序元素移动到正确的位置。3重复上述过程,直到整个数组有序。时间复杂度最好情况:O(n)(数组已有序)最坏情况:O(n²)(数组逆序)C++实现代码****代码解释1bubbleSort函数实现冒泡排序:使用双重循环,外层控制遍历次数,内层进行元素比较和交换。swapped标志检测是否发生交换,若未交换则提前退出。2main函数测试排序效果:初始化数组,调用排序函数。输出排序前后的数组,验证结果。优化添加swapped标志以提前退出,减少不必要的遍历,提升效率。输出示例

1

2

排序前数组:64 34 25 12 22 11 90

排序后数组:11 12 22 25 34 64 90

数位while循环剥离

方法1

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main() {
int num = 12345;
while (num > 0) {
int lastDigit = num % 10; // 获取个位数
std::cout << "剥离的个位数是: " << lastDigit << std::endl;
num /= 10; // 去掉个位数
}
return 0;
}

从低位向高位剥离

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main() {
int num = 12345;
while (num > 0) {
int lastDigit = num % 10; // 获取个位数
std::cout << "剥离的数位是: " << lastDigit << std::endl;
num /= 10; // 去掉个位数
}
return 0;
}

从高位向低位剥离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <cmath>

int reverseNumber(int num) {
int reversedNum = 0;
while (num > 0) {
reversedNum = reversedNum * 10 + (num % 10);
num /= 10;
}
return reversedNum;
}

int main() {
int num = 12345;
num = reverseNumber(num);
while (num > 0) {
int lastDigit = num % 10;
std::cout << "剥离的数位是: " << lastDigit << std::endl;
num /= 10;
return 0;
}

夏令营c++笔记

截取字符串

字符串名.substr(1,2)//截取范围,下标从0开始

1
2
3
4
5
6
7
8
9
10
11
#include <bits/stdc++.h>
using namespace std;
string s;
int main()
{
cin>>s;
int a,b;
cin>>a>>b;
cout<<s.substr(a,b);
return 0;
}

消除字符串

字符串名.erase(0,1)

判断质数

要判断一个数是否为质数,我们可以使用优化的试除法。质数只能被1和它本身整除。以下是判断质数的C++代码及原理说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int n)
{
if(n<=1)
{
return false;
}
if(n<=3)
{
return true;
}
if(n%2==0 || n%3==0)
{
return false;
}
for(int i=5;i*i<=n;i+=6)
{
if(n%i==0 || n%(i+2)==0)
{
return false;
}
}
return true;
}
int main()
{
int n;
cout<<"输入一个整数:";
cin>>n;
if(isPrime(n))
{
cout<<n<<" 是质数。"<<endl;
}
else
{
cout<<n<<" 不是质数。"<<endl;
}
return 0;
}

原理说明

  1. 处理特殊情况:
    ○ 如果n小于等于1,直接返回false,因为质数必须大于1。
    ○ 如果n是2或3,直接返回true,因为它们是质数。
    ○ 如果n能被2或3整除,返回false,因为它们不是质数(除了2和3本身)。
  2. 优化的试除法:
    ○ 从5开始,检查到√n为止。
    ○ 由于所有质数大于3都可以表示为6k ± 1,所以每次增加6,并检查i和i+2是否能整除n。
    ○ 如果在循环中找到任何能整除n的数,返回false。
  3. 主函数:
    ○ 读取输入的整数n。
    ○ 调用isPrime函数判断n是否为质数,并输出结果。
    这个方法通过减少不必要的检查,提高了判断质数的效率。

最大公约数的函数

__gcd(1,2)

队列

队列定义

queue<int> 名

函数

1
2
3
4
5
6
queue<int> l;
l.push(1);//放入
l.front();//获取队首
l.pop();//出队
l.empty();//有数据T,无F
l.size();//返回长度

定义

stack<int>

函数

1
2
3
4
5
6
(constructor)
.empty()
.push()
.top()
.empty()
.size()

二分

模版代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int main()
{
int n,f=0;
cin>>n;
int a[900000]={};
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
int x;
cin>>x;
int l=0,r=n-1,res=-1;
while(l<=r)
{
int mid=l+(r-l)/2;
if(a[mid]>=x)
{
r=mid-1;
if(a[mid]==x)
{
f=1;
res=mid+1;
}
}
else
{
l=mid+1;
}
}
cout<<res;
return 0;
}

向左找

1
2
3
4
5
6
7
8
9
10
11
while(l<r)
{
int mid=l+(r-l)/2;
if(a[mid]>m)
{
r=mid;
}
else
{
l=mid+1;
}
  • Title: jiezhi(易)的c++知识库
  • Author: 易jiezhi 个人空间
  • Created at : 2025-08-12 10:07:25
  • Updated at : 2025-08-13 10:38:23
  • Link: https://jiezhi.com/2025/08/12/jiezhi(易)的c++-知识库/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments