格式化输入输出 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格式
控制符
作用
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格式化输出
%.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
整数进行运算的结果还是整数
自动数据类型转换规则 转换规则:低精度->高精度
数据储存到与其数据类型不一致的变量中,也会发生自动数据类型转换
总结规律 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()
函数 定义函数的语法格式 数据类型 函数名()
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-1 。 a[i][j] 与 a[i][n-1-j] **垂直对称。
行对称 水平对称的两个元素, **行下标相加 的结果等于 n-1 。 a[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; 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
性质:对**差分数组 求 前缀和 ,得到 原数组 **。
栈
在计算机中有一种容器:
容器只有一个口进行数据的存取。
** 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; 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++实现代码 ****代码解释 1 bubbleSort 函数实现冒泡排序: ○ 使用双重循环,外层控制遍历次数,内层进行元素比较和交换。 ○ swapped 标志检测是否发生交换,若未交换则提前退出。 2 main 函数测试排序效果: ○ 初始化数组,调用排序函数。 ○ 输出排序前后的数组,验证结果。 优化 ● 添加 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 ; }
原理说明
处理特殊情况: ○ 如果n小于等于1,直接返回false,因为质数必须大于1。 ○ 如果n是2或3,直接返回true,因为它们是质数。 ○ 如果n能被2或3整除,返回false,因为它们不是质数(除了2和3本身)。
优化的试除法: ○ 从5开始,检查到√n为止。 ○ 由于所有质数大于3都可以表示为6k ± 1,所以每次增加6,并检查i和i+2是否能整除n。 ○ 如果在循环中找到任何能整除n的数,返回false。
主函数: ○ 读取输入的整数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 (); 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 ; }