任何进制都没有他的本身:因为他们是从0开始的
10进制:
0 1 2 3 4 5 6 7 8 9 10 11
2进制:
0 1 10 11 100 101 110 111 1000
8进制:
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20
16进制:
0 1 2 3 4 5 6 7 8 9 A B C D E F
10 11 12 13 14 15 16 17 18 19 1A
1B 1C 1D 1E 1F 20 21 22 23 24 25
(1)10进制转R进制(任意进制的意思):采用除R取余法
如果转成10进制,就除以10
如果转成2进制,就除以2
易错点:从后往前读
(2)R进制转10进制:按权展开
所谓权就是:主要看R进制,R进制如果是10进制,那么权就是10的多少次方,如果R进制是2进制,那么权就是2的多少次方。(记得从低位开始)
注意:任何进制的0次方都是1
简便方法:2进制转10进制
例子:1010 转成10进制
1 0 1 0
8 4 2 1
将有1 的地方对应的数加起来 得到:8+2=10
假设是6位2进制数:101010
1 0 1 0 1 0
32 16 8 4 2 1
对应的1加起来:32+8+2=42
1、将定义1-F的16进制对于的数组记忆下来
#include<bits/stdc++.h>
using namespace std;
string t[16]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
int main(){string s,r;cin>>s;int x;for(int i=0;i<s.size();i++){if(isdigit(s[i])){x=s[i]-'0';}else{x=s[i]-'A'+10;}r=r+t[x];}while(r[0]=='0'){r.erase(0,1);}if(r==""){cout<<0;}else{cout<<r;}
}
将以下的二进制数转换为八进制数:
将以下的二进制数转换为十六进制数:
将以下的八进制数转换为二进制数:
将以下的十六进制数转换为二进制数:
提示:
注意:对于二进制、八进制和十六进制的转换,可能存在多种不同的表示方法(例如前置零),但这些答案都是基于标准的转换方法得到的。
祝你学习愉快!
思路:任何进制的转换函数
1、定义一个数组
2、采用while获取获取值不为0
3、取出对应进制的余数
4、计数
5、得到对应进制的商
#include<bits/stdc++.h>
using namespace std;bool huiwen(int n,int d){bool r=true;int k=0;int a[1000]={0};while(n!=0){a[k]=n%d;k++;n=n/d;}for(int i=0;i<k/2;i++){if(a[i]!=a[k-i-1]){r=false;break;}}return r;
}
int main(){int a[110],n;cin>>n;for(int i=0;i<n;i++){cin>>a[i];if(huiwen(a[i],10)==false&&(huiwen(a[i],16)==true)||(huiwen(a[i],2)==true)){cout<<a[i]<<endl;}} return 0;
}
int类型数值范围:2 * 10的9次方(大概可以表示10位数)
long long 数值范围:9 * 10的18次方(大概可以表示的是19位数)
为什么要使用高精度运算?
因为运算数字已经超出了标准类型所能承载的最大限度,所以只能用高精度运算进行计算,同样的高精度运算也叫做大整数运算
高精度运算步骤:
高精度加法运算:
1、两个字符串读入,三个数组
2、将字符串翻转,逆序传入数组
3、遍历数组,进行加法运算
4、遍历数组,处理进位
5、处理前导0
6、倒序输出
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
//1、定义两个字符串,用于输入高精度整数
string s1,s2;
//2、三个数组
const int MAX_SIZE = 250;//定义常数
int a1[MAX_SIZE],a2[MAX_SIZE],a3[MAX_SIZE];
int main()
{cin>>s1>>s2;//4、存入数组 for(int i=0; i<s1.size(); i++){a1[i] = s1[s1.size()-i-1] - '0';}for(int i=0; i<s2.size(); i++){a2[i] = s2[s2.size()-i-1] - '0';}//5、相加 int carry = 0;for(int i=0; i<MAX_SIZE; i++){a3[i] = a1[i] + a2[i];}for(int i=0; i<MAX_SIZE; i++){if(a3[i] >= 10){carry = a3[i] / 10;a3[i] = a3[i] % 10;a3[i+1] += carry; }}//6、去掉前导0int len = MAX_SIZE-1;while(a3[len] == 0 && len>0){len--;} //输出 for(int i=len; i>=0; i--) {cout<<a3[i];}return 0;
}
1、输入两个字符串
2、判断结果是正数还是负数((1)先比较长度 (2)长度相等比较字典码大小)
3、倒叙存入数组(字符转数字)
4、定义一个len=s1.size()-1(默认s1字符串是最大的)
5、遍历长度为len的数组,进行加减运算((1)先判断是否要进位(2)在进行加减)
6、先判断是否要输出负号以及去掉前导0
7、倒叙输出
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
const int MAX_SIZE = 250;
int a[MAX_SIZE],b[MAX_SIZE],c[MAX_SIZE];
int len,p;
char f='+';
int main(){//1、输入字符串 cin>>s1>>s2;//2、判断结果是正数还是负数//(1)先比较长度 (2)长度相等比较字典码大小 if(s1.size()<s2.size()||(s1.size()==s2.size()&&s1<s2)){f='-';//swap可以交换数组 字符串 字符 整形 swap(s1,s2);}for(int i=0;i<s1.size();i++){a[i]=s1[s1.size()-i-1]-'0';}for(int i=0;i<s2.size();i++){b[i]=s2[s2.size()-i-1]-'0';}len=s1.size()-1;//先判断需不需要进位//再进行加减 for(int i=0;i<=len;i++){if(a[i]<b[i]){a[i+1]=a[i+1]-1;a[i]=a[i]+10;}c[i]=a[i]-b[i];}if(f=='-') cout<<f;//去掉前导0 while(c[len] == 0 && len>0){len--;} for(int i=len;i>=0;i--){cout<<c[i];}return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAX_SIZE=250;
string s;
int b;
int a[MAX_SIZE];
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>s>>b;for(int i=0;i<s.size();i++){a[i]=s[s.size()-i-1]-'0';}for(int i=0;i<s.size();i++){a[i]=a[i]*b;}for(int i=0;i<s.size()+4;i++){if(a[i]>=10){a[i+1]=a[i+1]+a[i]/10;a[i]=a[i]%10;}}int len=MAX_SIZE;while(a[len]==0&&len>0){len--;}for(int i=len;i>=0;i--){cout<<a[i];}return 0;
}
高精度乘高精度步骤:
(1)输入两个字符串
(2)倒序存入数组
(3)利用(i+j)进行错位相加,并且判断进位
(4)去掉前导0,len长度为两个字符串相加的长度-1,必须要大于0,因为要保证有一个数,如果len=0那么就会被减成-1,访问数组就会越界
(5)倒序输出
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[250],b[250],c[500];
int len;
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>s1>>s2;for(int i=0;i<s1.size();i++){a[i]=s1[s1.size()-i-1]-'0';}for(int i=0;i<s1.size();i++){b[i]=s2[s2.size()-i-1]-'0';}for(int i=0;i<s1.size();i++){for(int j=0;j<s2.size();j++){c[i+j]=c[i+j]+a[i]*b[j];if(c[i+j]>9){c[i+j+1]=c[i+j+1]+c[i+j]/10;c[i+j]=c[i+j]%10;}}}len=s1.size()+s2.size()-1;while(c[len]==0&&len>0){len--;}for(int i=len;i>=0;i--){cout<<c[i];}return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[110]={1};
int main(){int n,sum=0,k=1;cin>>n;for(int i=0;i<n;i++){for(int j=0;j<k;j++){a[j]*=2;}for(int z=0;z<n;z++){if(a[z]>=10){a[z+1]+=a[z]/10;a[z]%=10;}}if(a[k]!=0){k++;}} for(int i=k-1;i>=0;i--){cout<<a[i];}return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[1000]={1},r[1000];
int main(){int n,sum=0,k1=1,k2=0;cin>>n;int len=0;for(int i=0;i<n;i++){for(int j=0;j<k1;j++){a[j]*=2;}for(int z=0;z<n;z++){if(a[z]>=10){a[z+1]+=a[z]/10;a[z]%=10;}}if(a[k1]!=0){k1++;}len=max(k1,len);for(int j=0;j<len;j++){r[j]+=a[j];if(r[j]>=10){r[j+1]+=r[j]/10;r[j]%=10;} }if(r[len]!=0){len++;}
}for(int i=len-1;i>=0;i-- ){cout<<r[i];}return 0;
}
什么是递推?
递推算法是一种用若干步可重复运算来描述复杂问题的方法,递推法是一种重要的数学方法,也是编程中解决问题的一个重要方法。
斐波那契数列求第n项的值:
(1)第一项、第二项的值都为1
(2)A(n) = A(n-1) + A(n-2)
1、采用递归的方法
缺点:随着n的值越来越大,重复求解的项会越来越多,这颗树就会越来越大,因此很耗费时间。
#include <iostream>
using namespace std;
//递归
int num(int n)
{int r;if(n==1 || n==2){//递归的结束条件 r = 1; }else{r = num(n-1) + num(n-2);}}
int main()
{int n;//求第几项cin>>n;cout<<num(n)<<endl; return 0;}
2、记忆数组
#include <iostream>
using namespace std;
long long a[60],n;
int main()
{cin>>n;a[1] = 1;a[2] = 1;for(int i = 3; i<=n; i++){a[i] = a[i-1] + a[i-2];}cout<<a[n]<<endl;return 0;
}
#include <iostream>
using namespace std;
int main()
{int x;//最后剩余的数量x = 1;for(int i=2; i<=10; i++){x = (x+1) * 2;} cout<<x;return 0;
}
第一种方法:双重for循环
#include <iostream>
using namespace std;
int main()
{int n,sum=0;cin>>n;for(int i=1; i<=n; i++){for(int j=1; j<=i; j++){sum += j;}} cout<<sum;return 0;
}
第二种方法:递推公式
A(n)= A(n-1) + n;
(1)定义一个二维数组
(2)输入的时候内层循环是小于i的(因为是三角形)
(3)外层循环从第n-1行开始,内层循环从1开始到i
(4)选取相邻两条线找值最大
(下标是a[x+1][y],a[x+1][y+1])
(5)输出是a[1][1]
#include <iostream>
using namespace std;
int a[110][110];
int n;
int main()
{cin>>n;for(int i=1; i<=n; i++){for(int j=1; j<=i;j++){cin>>a[i][j];}}for(int i=n-1; i>=1; i--){for(int j=1; j<=i;j++){a[i][j] += max(a[i+1][j],a[i+1][j+1]);}} cout<<a[1][1];return 0;
}
#include <iostream>
using namespace std;
string he(string s1,string s2)
{string r;int a[1000]={0};int b[1000]={0};int c[1000]={0};for(int i=0;i<s1.size();i++){a[i]=s1[s1.size()-i-1]-'0';}for(int i=0;i<s2.size();i++){b[i]=s2[s2.size()-i-1]-'0';}int len=max(s1.size(),s2.size());for(int i=0;i<len;i++){c[i]+=a[i]+b[i];if(c[i]>=10){c[i+1] = c[i+1] + c[i] / 10;c[i] = c[i] % 10; }}if(c[len]!=0){len++;}for(int i=len-1;i>=0;i--){r=r+(char)(c[i]+'0');}return r;
}
string cheng(string s)
{string r;int len=s.size();int a[1000]={0};for(int i=0;i<s.size();i++){a[i]=s[s.size()-i-1]-'0';}for(int i=0;i<len;i++){a[i]*=2;}for(int i=0;i<s.size();i++){if(a[i]>=10){a[i+1]+=a[i]/10;a[i]%=10;}if(a[len]!=0){len++;}}for(int i=len-1;i>=0;i--){r=r+to_string(a[i]);}return r;
}
int main()
{string x,y,z;int i,n;cin>>n;x="1";y="2";if(n==1){cout<<x;}else if(n==2){cout<<y;}else{for(int i=3;i<=n;i++){z=he(cheng(y),x);x=y;y=z;}}cout<<z;return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n;int fun(int i) {if (i <= n) {return i + fun(i + 1);} else {return 0;}
}int main() {cin >> n;cout << fun(1);
}
#include <bits/stdc++.h>
using namespace std;
int fun(int n,int c){if (n!=1){if (n%2==0){return fun(n/2,1+c);}else{return fun(n*3+1,1+c); }}else{return c;}
}
int main(){int n;cin>>n;cout<<fun(n,0);
}
#include <bits/stdc++.h>
using namespace std;
int a[11][11];void fun(int start, int len, int x) {int i, j;if (len > 0) {for (j = start; j <= start + len - 1; j++) {a[start][j] = x;x++;}for (i = start + 1; i <= start + len - 1; i++) {a[i][start + len - 1] = x;x++;}for (j = start + len - 2; j >= start; j--) {a[start + len - 1][j] = x;x++;}for (i = start + len - 2; i >= start + 1; i--) {a[i][start] = x;x++;}fun(start + 1, len - 2, x);}}int main() {int n;cin >> n ;fun(1, n, 1);for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cout << setw(3) << a[i][j];}cout << endl;}return 0;
}
第一种写法:分方向
#include <bits/stdc++.h>
using namespace std;
int a[11][11];
int n, m;void fun(int x, int y, int k) {a[x][y] = k;if (y + 1 <= m && a[x][y + 1] == 0)fun(x, y + 1, k + 1);if (x + 1 <= n && a[x + 1][y] == 0)fun(x + 1, y, k + 1);if (y - 1 >= 1 && a[x][y - 1] == 0)fun(x, y - 1, k + 1);if (x - 1 >= 1 && a[x - 1][y] == 0)fun(x - 1, y, k + 1);
}int main() {cin >> n >> m;fun(1, 1, 1);for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cout << setw(3) << a[i][j];}cout << endl;}}
第二种写法是方向数组
1.定义字符数组/整数数组(看输入数据类型决定)
2.定义fx[4],fy[4],tx(下一个方向的x),ty(下一个方向的y)
3.根据题目要求的方向进行方向数组赋值,左右为y,上下为x,右y+1,左y-1,下x+1,上x-1;
4.开始写递归函数
(1)进来先赋值/标记
(2)遍历四个方向
(3)判断边界一般是tx、ty、数组的初始值/标记数组的初始值
(4)fun(tx,ty,k+1)递归下一个点
#include <bits/stdc++.h>
using namespace std;
int n, m, tx, ty;
int a[11][11];
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
void fun(int x, int y, int k) {a[x][y] = k;for (int i = 0; i < 4; i++) {tx = x + fx[i];ty = y + fy[i];if (tx <= n && tx >= 1 && ty <= m && ty >= 1 && a[tx][ty] == 0) {fun(tx, ty, k + 1);}}
}
int main() {cin >> n >> m;fun(1, 1, 1);for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cout << setw(3) << a[i][j];}cout << endl;}return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n, ha, la, hb, lb, tx, ty;
int fx[4] = {1, -1, 0, 0};
int fy[4] = {0, 0, 1, -1};
int a[110][110];void dfs(int x, int y) {a[x][y] = 1;for (int i = 0; i < 4; i++) {tx = x + fx[i];ty = y + fy[i];if (tx >= 1 && tx <= n && ty >= 1 && ty <= n && a[tx][ty] == 0) {if (tx == hb && ty == lb) {cout << "YES";exit(0);}dfs(tx, ty);}}
}int main() {cin >> n;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> a[i][j];}}cin >> ha >> la >> hb >> lb;if(a[ha][la]==1||a[hb][lb]==1){cout<<"NO";return 0;}else{dfs(ha, la);} cout << "NO";return 0;
}
DFS一般步骤:
1、进来先给数组赋值
2、开始遍历四个方向
3、判断在是否在可实行范围内
4、在可实行范围内调用递归
涉及知识点:
最大最小值头文件:
#include<climits>
#include <limits.h>
INT_MAX: 表示int类型的最大值;
INT_MIN: 表示int类型的最小值;
详细可看文档:C/C++之最值limits.h(climits)和limits头文件
#include <iostream>
#include <climits>//最大值最小值头文件
using namespace std;
char a[50][50];
int d[50][50];
int fx[4] = {1,0,-1,0};
int fy[4] = {0,1,0,-1};void dfs(int x,int y,int step)
{//1、进来先将数组赋值d[x][y] = step; //2、开始遍历四个方向 int tx,ty;for(int i=0; i<4; i++){tx = x + fx[i];ty = y + fy[i];//判断是否在这个范围if(a[tx][ty] == '.' && step+1<d[tx][ty]){dfs(tx,ty,step+1);} } }
int main()
{int r,c;cin>>r>>c;for(int i=1; i<=r; i++){for(int j=1;j<=c; j++){cin>>a[i][j];d[i][j] = INT_MAX;}}//深度搜索 dfs(1,1,1); cout<<d[c][r];return 0;
}
方向数组如何规定方向:
左、上、右、下
首先数组一般是:d[x][y](看成一个二维数组)
证明:
x决定的是上下方向(行方向),下走为1,上走为-1左、上、右、下
fx 0 -1 0 1
y决定的是左右方向(列方向),右走为1,左走为-1左、上、右、下
fy -1 0 1 0主要思路:
1、定义两个数组一个用于存储地图,一个用于存储走过的路径
2、dfs对于本题的一般步骤:
(1)标记数组走过的路径并且记录该路径的值
(2)判断是否到达终点
(3)循环遍历四个方向,在循环里面判断下一个位置是否是可实行范围
(4)在可实行范围里面递归寻找下一个点
#include<iostream>
using namespace std;
char a[30][30];//输入地图
int r[410][3];
int n;
//左、上、右、下
int fx[4] = {0,-1,0,1};
int fy[4] = {-1,0,1,0};
void print(int k)
{for(int i=1; i<=k; i++){cout<<"("<<r[i][1]<<","<<r[i][2]<<")";if(i != k){cout<<"->";}}exit(0);
}void dfs(int x,int y,int k)
{int tx,ty;//标记or赋值 r[k][1] = x;r[k][2] = y;//将走过的的路径标记为1a[x][y] = '1'; if(x==n && y==n){print(k);}for(int i=0;i<4;i++){tx = x + fx[i];ty = y + fy[i];if(a[tx][ty] == '0'){dfs(tx,ty,k+1);}}}
int main()
{cin>>n;for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){cin>>a[i][j];}}dfs(1,1,1);return 0;
}
重点:记得搜索到终点return可以节约时间。
#include <iostream>
using namespace std;
int n,m;
int d[20][3];
int c = 0 ;//计数
//方向数组
void print(int k)
{c++;cout<<c<<":";for(int i=1; i<k; i++){cout<<d[i][1]<<","<<d[i][2]<<"->";}cout<<n<<","<<m<<endl;
}
int fx[2] = {1,0};
int fy[2] = {0,1};
void dfs(int x,int y, int k)
{//1、先记录路线d[k][1] = x;d[k][2] = y;//2、判断是否到达终点 if(x == n && y == m){print(k);return ; //到终点停止递归 }int tx,ty;for(int i=0; i<2; i++){tx = x + fx[i];ty = y + fy[i]; if(tx>=1 && tx<=n && ty>=1 && ty<=m){dfs(tx,ty,k+1);}} }
int main()
{cin>>n>>m;dfs(1,1,1);return 0;
}
回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得问题的解,先选择一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前搜索,如此反复进行,直至得到解或证明无解。
如迷宫问题:进入迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其它方向是否还有路可走,如果有路可走,则沿该方向再向前试探:如果已无路可走,则返回一步,再看其它方向是否还有路可走:如果有路可走,则沿该方向再向前试探。按此原则不断搜索回溯再搜索,直到找到新的出路或从原路返回入口处无解为止
#include <iostream>
using namespace std;
int n;
bool b[10][10];//默认为false
int r[30][3];
int temp;//计数
//方向数组
//右、下、左、上
int fx[4] = {0,1,0,-1};
int fy[4] = {1,0,-1,0};void print(int k)
{temp++;cout<<temp<<":";for(int i=1; i<k; i++){cout<<r[i][1]<<","<<r[i][2]<<"->";}cout<<n<<","<<n<<endl;
} void dfs(int x,int y,int k)
{//1、进来先标记路线 r[k][1] = x;r[k][2] = y;//2、判断到达终点就返回if(x==n && y==n){print(k);return ;} //3、遍历四个方向 int tx,ty;for(int i=0; i<4; i++){tx = x + fx[i];ty = y + fy[i];if(tx>=1&& tx <=n && ty >=1 && ty<=n && b[tx][ty] == false){b[tx][ty] = true;dfs(tx,ty,k+1);b[tx][ty] = false;}}
}
int main()
{cin>>n;b[1][1] = true;dfs(1,1,1); return 0;
}
此类全排列类型题目:
1、需要带有标记数组选过的路径
2、遍历所有可能的选项
3、标记已经走过的路径
4、判断是否到达最终路径,若无到达则继续递归
5、递归结束要回到初始状态
#include <iostream>
using namespace std;int n;
int a[10];
bool r[10];
void print(int k)
{for(int i=1; i<=k; i++){cout<<a[i]<<" ";}cout<<endl;
}
void fun(int k)
{//1、遍历所有可能的结果for(int i=1; i<=n; i++){if(r[i] == false){//2、赋值 a[k] = i;//3、标记选过的数r[i] = true;//4、判断范围是否到达 if(k == n){print(k);}else{fun(k+1);}//5、递归结束需要回到之前状态r[i] = false;}}
}
int main()
{cin>>n;fun(1);return 0;
}
此题知识点:
判断素数代码需要记忆():
bool Sushu(int n)
{if(n<2) return false;for(int i=2; i * i <= n; i++){if(n % i==0){return false;}}return true;
}
#include <iostream>
using namespace std;
int n,temp;
bool b[20];
int a[30];
void print(int k)
{temp++;cout<<temp<<":";for(int i=1; i<=k; i++){cout<<a[i];if(i!=k){cout<<" ";}else{cout<<endl;}}
}bool Sushu(int n)
{if(n<2) return false;for(int i=2; i*i <= n; i++){if(n % i==0){return false;}}return true;
}
void fun(int k)
{for(int i=1; i<=n; i++){if(b[i] == false && (k==1 || Sushu(i+a[k-1]) == true))//难点判断范围{b[i] = true;a[k] = i;if(k==n && Sushu(a[k] + a[1])){print(k);//这里不能用return;会直接结束掉全部程序} else{fun(k+1);}b[i] = false;}}
}
int main()
{cin>>n;fun(1);cout<<"total:"<<temp;return 0;}
#include <iostream>
using namespace std;
int a[110][110];//存储矩阵
int q[10110][3];//存储队列(遍历过的点)
//右、下、左、上
int fx[4]={0,1,0,-1};
int fy[4]={1,0,-1,0};
int tx,ty;//表示访问的下一个点的坐标
int k = 1;//表示计数
//head表示头指针 tail表示尾指针
int n,m,head = 1,tail = 1;
int main()
{cin>>n>>m;//进来先标记为 1a[1][1] = k;//标记遍历数组的横纵坐标q[1][1] = 1;q[1][2] = 1;//当head<=tail时,说明队列还有点没有尝试标记过四个方向 while(head<=tail){for(int i=0; i<4; i++){for(int j=0; j<4;j++){tx = q[head][1] + fx[i];ty = q[head][2] + fy[i];//如果新点在矩阵内,且新点没有访问过if(tx>=1 && tx<=n && ty>=1 && ty<=m && a[tx][ty]==0){//存入点 尾指针++tail++;q[tail][1] = tx;q[tail][2] = ty;a[tx][ty] = ++k; }}}//使得标记过四个方向的点出队列 head++;} for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){cout<<a[i][j]<<" "; }cout<<endl;}return 0;
}
#include <bits/stdc++.h>
using namespace std;
int a[1010][1010];
bool f[1010][1010];
int q[10000100][3];
int fx[4] = {0,0,1,-1};
int fy[4] = {1,-1,0,0};
int head = 1,tail = 1,tx,ty;//标记头尾指针为1
int main()
{//1、输入数组 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int n,m,p1,p2;cin>>n>>m>>p1>>p2;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){cin>>a[i][j]; }}//2、第一个点入队列 q[1][1] = p1;q[1][2] = p2;f[p1][p2] = true;//3、while循环头指针小于尾指针 while(head<=tail){//4、遍历四个方向 for(int i=0; i < 4; i++){tx = q[head][1] + fx[i];ty = q[head][2] + fy[i];//5、如果新点可达并且没有出边界if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&f[tx][ty] == false && a[tx][ty] <= a[p1][p2]) {//6、进来先标记和入队列 f[tx][ty] = true;tail++;q[tail][1] = tx;q[tail][2] = ty; }}head++;}cout<<tail;//走过多少点 return 0;}
1442 - 走出迷宫的最短路径
#include <bits/stdc++.h>
using namespace std;
int a[150][150];
int q[40000][3];
int fx[4] = {1,-1,0,0};
int fy[4] = {0,0,1,-1};
int tx,ty,head = 1,tail = 1;
void print(int k)
{if (q[k][3] != 0 ){print(q[k][3]);}cout<<"("<<q[k][1]<<","<<q[k][2]<<")";if(k != tail){cout<<"->";}
}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int n,m,s1,s2,e1,e2;cin>>n>>m;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){cin>>a[i][j];}}cin>>s1>>s2>>e1>>e2;q[1][1] = s1;q[1][2] = s2;q[1][3] = 0;//没有前驱点while(head<= tail) {for(int i=0; i<4; i++){tx = q[head][1] + fx[i];ty = q[head][2] + fy[i];if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0){a[tx][ty] = 1;tail++;q[tail][1] = tx;q[tail][2] = ty;q[tail][3] = head;if(tx==e1 && ty==e2){print(tail);return 0;}}}head++;}cout<<"no way";return 0;
}
#include<bits/stdc++.h>
using namespace std;
char a[200][200];
int q[40000][3];
int tx,ty,head=1,tail=1;
int fx[8] = {-1,-2,-2,-1,1,2,2,1};
int fy[8] = {-2,-1,1,2,2,1,-1,-2};
int main()
{int n,m,s1,s2,e1,e2;cin>>m>>n;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){cin>>a[i][j];if(a[i][j]=='K'){s1=i;s2=j;}if(a[i][j]=='H'){e1=i;e2=j;}}}//起始点进入队列 q[1][1] = s1;q[1][2] = s2;q[1][3] = 0;while(head<=tail){//遍历8个方向 for(int i=0; i<8; i++){tx = fx[i] + q[head][1];ty = fy[i] + q[head][2];if(a[tx][ty]=='.'||a[tx][ty]=='H'){a[tx][ty] = '*';tail++;q[tail][1] = tx;q[tail][2] = ty;q[tail][3] = q[head][3]+1;if(tx==e1&&ty==e2){cout<<q[tail][3];return 0; } }}head++;}return 0;}
分治:将一个规模为 N 的问题分解为 个规模较小的子问题,这些子问题相互独立且与原问题性质相同。
求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法。二分查找步骤:
1、定义一个初始位置 r(需要赋初始值),left,right,mid
2、while循环条件固定位left<=right
3、先判断中点是不是目标值,如果是就break;
4、在判断是在左边,左边将mid-1赋值给right
5、在判断是在右边,右边将mid+1值赋给left
6、注意重点:
(1)left = mid+1 左加
(1)right = mid-1 右减
分查找(Binary Search)是一种在有序数组中查找特定元素的高效算法。在讨论二分查找的最佳结果时,我们通常是在讨论其最佳时间复杂度,即在最理想的情况下,算法需要比较的次数。
在最佳情况下,二分查找的时间复杂度是 O(1),这发生在要查找的元素正好是数组的中间元素时。也就是说,在最佳情况下,你只需要进行一次比较就能找到目标元素。
二分查找算法的最坏情况时间复杂度是 O(log n),其中 “n” 是数组中的元素数量。这种情况发生在所查找的元素位于数组的一端或根本不存在于数组中。
以下是一个简单的代码实例:
#include <iostream>
using namespace std;int main() {int n;cout << "输入一个正整数: ";cin >> n; // 用户输入一个数// 这个 for 循环每次以 2 的幂进行迭代for (int i = 1; i < n; i *= 2) {// 每次循环,i 都翻一番cout << "当前 i 的值是: " << i << endl;}return 0;
}如果您想了解对于不同的 2 的幂,循环的迭代次数是多少,下面是几个示例:1. 如果 `n` 等于 2,即 (2^1),那么循环只需迭代 1 次,因为 `i` 初始值为 1,循环第一次迭代就变成了 2,满足了条件。2. 如果 `n` 等于 4,即 (2^2),那么循环需要迭代 2 次。第一次迭代 `i` 变为 2,第二次迭代 `i` 变为 4。3. 如果 `n` 等于 8,即 (2^3),那么循环需要迭代 3 次。`i` 的值将先后变为 2、4 和 8。4. 如果 `n` 等于 16,即 (2^4),那么循环需要迭代 4 次。`i` 的值将先后变为 2、4、8 和 16。5. 如果 `n` 等于 32,即 (2^5),循环需要迭代 5 次。`i` 的值将先后变为 2、4、8、16 和 32。依此类推,如果 `n` 是 (2^x),那么循环就需要迭代 `x` 次。这是因为每次迭代都会使 `i` 翻倍,所以 `i` 会以 2 的幂次增长:(2^1, 2^2, 2^3, ldots, 2^x)。总之,当 `n` 是 2 的幂时,循环的迭代次数正好是 `n` 的以 2 为底的对数,即 (log_2(n))。如果 `n` 不是 2 的幂,循环的迭代次数将是大于 (log_2(n)) 的最小整数。
相关公式展示:log一般将底数2。
开区间写法
#include <iostream>
using namespace std;
int a[1000000];
int main()
{int n,x,mid,left,right,r; cin>>n;for(int i=0; i<n; i++){cin>>a[i];}cin>>x;left = 0;right = n-1;r = -1;//给一个初始位置while(left<=right){mid = (left+right) / 2;if(a[mid] == x){r = mid;break;}else if(x<a[mid]){right = mid - 1;}else if(x>a[mid]){left = mid + 1;}} //本身是从零开始的 cout<<(r==-1 ? -1 : r+1)<<endl;return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n,x;cin>>n;int a[n+5];for(int i=1;i<=n;i++){cin>>a[i];}cin>>x;int l=1,r=n+1;while(l<r){int mid=(l+r)/2;if(x<a[mid]) r=mid;else if(x>a[mid]) l=mid+1;else{cout<<mid;return 0;}}cout<<-1;return 0;
}
递归解法:
#include <bits/stdc++.h>
using namespace std;int n, a[1000000], x;int fun(int left, int right)
{if (left > right) return -1;int mid = (left + right) / 2;if (x == a[mid]){return mid + 1;}else if (x < a[mid]){return fun(left, mid - 1);}else if (x > a[mid]){return fun(mid + 1, right);}}int main()
{cin >> n;for (int i = 0; i < n; i++){cin >> a[i];}cin >> x;cout << fun(0, n - 1) << endl;return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[100005],b[100005];
int f(int n,int m,int x){int l=0,r=n-1;while(l<=r){int mid=l+r>>1;if(a[mid]<x) l=mid+1;else if(a[mid]>x) r=mid-1;else return 1;}return 0;
}
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n,m;cin>>n>>m;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<m;i++) cin>>b[i];sort(a,a+n);sort(b,b+m);for(int i=0;i<m;i++){if(f(n,m,b[i])) cout<<b[i]<<" ";}return 0;
}
本题的快排思想:
1、左右指针赋值
2、基准值赋值
3、第一次划分子区间
4、寻找不符合的左、右区域
5、将两边不符合的值进行交换
6、交换后需要下标增加和减少
7、调用递归重新将左右子区域划分
这是一个经典的快速排序(Quick Sort)算法的实现。快速排序的平均时间复杂度为O(n log n),但最坏情况下时间复杂度为O(n^2)。 在你的代码中,快速排序递归调用的方式可能导致最坏情况的发生,因此最坏情况下时间复杂度为O(n^2)。
快速排序的时间复杂度的平均和最坏情况取决于选择的基准元素以及数据的分布情况。在最好情况下,每次选择的基准元素都能将数组均匀地分成两部分,此时时间复杂度接近O(n log n)。
#include <bits/stdc++.h>
using namespace std;int n, a[100000];void quick(int left, int right)
{if (left >= right) return; // 增加的基本情况检查,避免不必要的递归调用int i = left, j = right;//中轴值有可能是会被改变的,所以需要用额外的单独变量进行记忆下来int pivot = a[(left + right) / 2]; // 保存中间值while (i <= j){while (a[i] < pivot) i++;while (a[j] > pivot) j--;if (i <= j){swap(a[i], a[j]);i++;j--;}}if (left < j) quick(left, j);if (i < right) quick(i, right);
}int main()
{cin >> n;for (int i = 0; i < n; i++){cin >> a[i];}quick(0, n - 1);for (int i = 0; i < n; i++){cout << a[i] << " ";}return 0;
}
冒泡排序思路:
(1)外层循环-每轮要排的次数
(2)内层循环-循环到下标为几的数
(3)外层循环排n个数则要循环n-1轮
(4)内层循环不需要访问到最后的下标 下标应该是n-i-1
#include <iostream>
using namespace std;
int a[1000],n;
int main()
{cin>>n;for(int i=0; i < n; i++){cin>>a[i];}for(int i=1; i<=n-1; i++)//轮次{for(int j=0; j<=n-i-1;j++){//内层循环下标从0开始遍历到n-i-1//下标从1开始遍历到n-i if(a[j] > a[j+1]){swap(a[j],a[j+1]);}}}for(int i=0; i<n; i++){cout<<a[i]<<" ";}return 0;}
#include <iostream>
using namespace std;
int a[1000],n;
int main()
{cin>>n;for(int i=1; i <= n; i++){cin>>a[i];}for(int i=1; i<=n-1; i++)//轮次{for(int j=0; j<=n-i;j++){//内层循环下标从0开始遍历到n-i-1//下标从1开始遍历到n-i if(a[j] > a[j+1]){swap(a[j],a[j+1]);}}}for(int i=1; i<=n; i++){cout<<a[i]<<" ";}return 0;}
#include<iostream> //包含输入输出头文件
#include<cmath>
using namespace std; //指定名字空间
int main()
{ //主函数int a[100]; //定义数组,大小100int N; //元素的实际个数int i = 0, j = 0; //循环变量,并进行初始化cin >> N; //输入元素个数//-------输入数据-----------for (i = 0; i<N; i++) //输入N个元素cin >> a[i]; //循环体只有一行//-------排序---------------for (i = 0; i<N - 1; i++) { //控制n-1趟冒泡for (j = 0; j<N - 1 - i; j++){if (a[j]>a[j + 1]) { //比较相邻的两个元素swap(a[j],a[j+1]); }}}//--------输出----------for (i = 0; i<N; i++) { //使用循环,输出N个元素cout << a[i] << " "; //输出a[i], 后加空格,不换行}cout << endl; //所有元素输出完之后才换行return 0; //函数返回
}
#include <iostream>
using namespace std;
int a[1000],n;
bool f;
int main()
{cin>>n;for(int i=0; i < n; i++){cin>>a[i];}for(int i=1; i<=n-1; i++)//轮次{f = false;//假设没有产生过交换 for(int j=0; j<=n-i-1;j++){if(a[j] > a[j+1]){swap(a[j],a[j+1]);f = true;//产生交换则为true }}if(f==false)//本轮没有产生过交换 {break;//则退出循环 }}for(int i=0; i<n; i++){cout<<a[i]<<" ";}return 0;}
选择排序思想:
(1)外层循环比较n-1轮
(2)内层循环找出最大的数的下标不是它本轮最后一个数的下标n-i
(3)交换a[ma] , a[n-i]
#include <iostream>
using namespace std;
int a[1000],n,ma;
int main()
{cin>>n;for(int i=0; i<n; i++){cin>>a[i];}for(int i=1; i<=n-1; i++){//假设每轮的最大值下标都是0ma = 0;for(int j=1; j<=n-i; j++){if(a[j]>a[ma]){ma = j;}}//如果第i轮最大数下标不是本轮的最后一个数(n-i) if(ma != n-i){swap(a[ma],a[n-i]);} }for(int i=0; i<n; i++) {cout<<a[i]<<" ";}return 0;
}
18.4 桶排序
桶排序也叫箱排序工作的原理是:统计每个元素出现的个数,然后利用桶的下标已经有序的原理,按照每个数出现的次数循环输出。
因此,桶排序要求数组元素数值必须是小范围内的数!
什么情况下不适合用桶排序?
如果数据量不大,但数据中有一个数特别大,则不适合用桶排序!
2,5,3,3,8,9,1,2,7,6,100000
#include<iostream>
using namespace std;
int a[1010],n,x;
int main()
{cin>>n;for(int i=0; i<n; i++){cin>>x;a[x]++;}//桶排序数值尽量在1-1000范围内 for(int i=1;i<=1000; i++){for(int j=1;j<=a[i]; j++){cout<<i<<" ";}}return 0;
}
插入排序将数组分成前后 2 块, 前一块: 有序区间;后一块: 无序区间;排序思想:从无序区间中选择一个数字,插入到有序区间中。有序区间扩大一位,无序区间减少一位。直到有序区间覆盖整个数组。
无序区间:i到 n-1
有序区间:0到i-1
#include <iostream>
using namespace std;
int a[10010],n,i,j,t;
int main()
{cin>>n;for(int i=0; i<n; i++){cin>>a[i];}//循环无序区(a[0]默认在有序区)for(i=1;i<n; i++){//将a[i]插入到有序区间//循环有序区,寻找a[i]应该插入的下标for(j=0; j<i; j++){//找到第一个比要插入的数大的数//其位置就是插入的位置if(a[j]>=a[i]){break;} } if(j != i){t = a[i];//现将啊a[i]存储起来//将a[i]插入到下标为j的位置//先将元素后移动for(int k = i-1; k>=j; k--){a[k+1] = a[k];} }a[j] = t; } for(i=0; i<n; i++){cout<<a[i]<<" "; }return 0;
}
方法一:dfs
#include <bits/stdc++.h>
using namespace std;
int a[110][110];
int ma;
int n;
void dfs(int x,int y, int sum)
{ma = max(ma,sum);if(x+1<=n){dfs(x+1,y,sum+a[x+1][y]);dfs(x+1,y+1,sum+a[x+1][y+1]);}
}
int main()
{cin>>n;for(int i=1; i<=n; i++){for(int j=1; j<=i; j++){cin>>a[i][j];}} dfs(1,1,a[1][1]);cout<<ma<<endl;return 0;}
方法二:递推求解
动态规划一般步骤:
1、存储数据的数组
2、一个标注动态规划过程值的数组
3、寻找状态转移方程
#include <bits/stdc++.h>
using namespace std;
int a[110][110];
int d[110][110];
int ma;
int n;
void dfs(int x,int y, int sum)
{ma = max(ma,sum);if(x+1<=n){dfs(x+1,y,sum+a[x+1][y]);dfs(x+1,y+1,sum+a[x+1][y+1]);}
}//递推求解
void fun1(void){for(int j=1; j<=n; j++){d[n][j] = a[n][j];}for(int i=n-1; i>=1; i--){for(int j=1; j<=i; j++){d[i][j] = a[i][j]+max(d[i+1][j],d[i+1][j+1]);}}
}
int main()
{cin>>n;for(int i=1; i<=n; i++){for(int j=1; j<=i; j++){cin>>a[i][j];}} fun1();cout<<d[1][1];return 0;}
方法三:记忆化搜索
#include <bits/stdc++.h>
using namespace std;
int a[110][110];
int d[110][110];
int ma;
int n;
//1、深度优先搜索
void dfs(int x,int y, int sum)
{ma = max(ma,sum);if(x+1<=n){dfs(x+1,y,sum+a[x+1][y]);dfs(x+1,y+1,sum+a[x+1][y+1]);}
}//2、递推求解
void fun1(void){for(int j=1; j<=n; j++){d[n][j] = a[n][j];}for(int i=n-1; i>=1; i--){for(int j=1; j<=i; j++){d[i][j] = a[i][j]+max(d[i+1][j],d[i+1][j+1]);}}
}//4、记忆化搜索
int fun3(int x,int y){if(x==n){return a[x][y];}else{if(d[x][y] != -1) return d[x][y];else{d[x][y] = a[x][y] + max(fun3(x+1,y),fun3(x+1,y+1));return d[x][y];}}
}
int main()
{cin>>n;memset(d,-1,sizeof(d)); for(int i=1; i<=n; i++){for(int j=1; j<=i; j++){cin>>a[i][j];}} cout<<fun3(1,1);return 0;}
#include <bits/stdc++.h>
using namespace std;
int a[110];
int dp[110];
int main()
{int n,ma=0;cin>>n;for(int i=1; i<=n; i++){cin>>a[i];}dp[1] = a[1];for(int i=2; i<=n; i++){dp[i] = max(dp[i-1]+a[i] , a[i]);ma = max(ma,dp[i]);}cout<<ma;return 0;}
1、定义两个数组 一个输入数组 一个dp数组
2、外层循环遍历dp数组,dp[i]始终默认为1
3、内层循环遍历到i-1,如果本位值大于前面的值则使用状态转移方程
4、状态转移方程dp[j]+1(上一位的加一)+本位的dp[i]比较(因为这里重复了多次的存储dp[i])
#include <bits/stdc++.h>
using namespace std;
int a[10010],ma;
int dp[10010];int main()
{int n;cin>>n;for(int i=1; i<=n; i++){cin>>a[i]; } for(int i=1; i<=n; i++){dp[i] = 1;for(int j=1; j<i; j++){if(a[i]>a[j]){dp[i] = max(dp[j]+1,dp[i]);}}ma = max(dp[i],ma);}cout<<ma;return 0;
}
#include <iostream>
using namespace std;
int a[100100],s=0,n,x;
int dp[100100];
int main()
{//解题步骤//1、划分方向//2、确定状态转移方程//3、寻找边界cin>>n>>x; a[1] = x;dp[1] = a[1];s = dp[1];for(int i=2; i<=n; i++){a[i] = (379 * a[i-1] + 131 ) % 997;dp[i] = max(dp[i-1],a[i]);s += dp[i];}cout<<s;return 0;}
#include <iostream>
using namespace std;
int a[110],s=0,n,x;
int dp[110];
int main()
{cin>>n;for(int i=1; i<=n;i++){cin>>a[i];}//2、交代边界的值dp[1] = a[1];dp[2] = max(a[1],a[2]);//因为这里最低的取数是两个for(int i=3; i<=n;i++){dp[i] = max(dp[i-1],dp[i-2]+a[i]);}cout<<dp[n];return 0;}
#include <iostream>
using namespace std;
int a[110],s=0,n,x,ans;
int dpa[110];
int dpb[110];
int main()
{cin>>n;for(int i=1; i<=n;i++){cin>>a[i];}for(int i=1;i<=n; i++){dpa[i] = 1;for(int j=1; j<i; j++){if(a[j]<a[i]){dpa[i] = max(dpa[i],dpa[j]+1);}}}for(int i=n; i>=1; i--){dpb[i] = 1;for(int j=n; j>i;j--){if(a[j]<a[i]){dpb[i] = max(dpb[i],dpb[j]+1);}}}for(int i=1;i<=n;i++){ans=max(ans,dpa[i]+dpb[i]-1);}cout<<n-ans;return 0;}
STL核心库的基本概念

vector定义的四种方法:
(1)vector <类型> 名字
vector <int> d;(2)vector <int> d(默认初始大小);
vector <int> d(10);(3)vector <int> d(n,t);
n为默认长度
t为默认初始值
vector <int> d(10,10);(4)vector <int> d[begin,end);
int a[] = {10,20,30,40,50};
//数组名是数组的首地址
vector <int> d(a,a+sizeof(a)/sizeof(int));
vector <类型> 名字
vector <int> d;#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{//vector 的定义vector <int> v;//size():返回vector实际存储多少个元素//cout<<v.size(); //常见错误:定义一个空vector//然后给vector赋值//v[0] = 1; v[1] = 2; v.push_back(10);v.push_back(20);v.push_back(30);print(v);return 0;
}
#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(30);//insert(位置,元素):位置必须要提供位置指针//向vector中下标为1的位置插入用元素100v.insert(v.begin()+1,100); print(v);return 0;
}
#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(30);//insert(位置,元素):位置必须要提供位置指针//向vector中下标为1的位置插入用元素100//v.insert(v.begin()+1,100); //向vector中下标为1的位置插入5个100v.insert(v.begin()+1,5,100); print(v);return 0;
}
#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(30);//insert(位置,元素):位置必须要提供位置指针//向vector中下标为1的位置插入用元素100//v.insert(v.begin()+1,100); //向vector中下标为1的位置插入5个100//v.insert(v.begin()+1,5,100); vector<int> v2;v2.push_back(100);v2.push_back(200);v.insert(v.begin(),v2.begin(),v2.end());print(v);return 0;
}
#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(30);vector<int> v2;v2.push_back(100);v2.push_back(200);v.insert(v.begin(),v2.begin(),v2.end());v.erase(v.begin(),v.begin()+2); print(v);return 0;
}
#include <bits/stdc++.h>
#include <vector>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}
}
int main()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(30);cout<<"第一个元素:"<<v.front()<<endl;cout<<"最后一个元素:"<<v.back()<<endl;print(v);return 0;
}
#include <bits/stdc++.h>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}cout<<endl;
}
int main()
{vector<int> v1;v1.push_back(10);v1.push_back(20);v1.push_back(30);vector<int> v2;v2.push_back(1000);v2.push_back(2000);v2.push_back(3000);swap(v1,v2);print(v1);print(v2);return 0;
}
#include <bits/stdc++.h>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}cout<<endl;
}
int main()
{vector<int> v1;v1.push_back(10);v1.push_back(20);v1.push_back(30);reverse(v1.begin(),v1.end());print(v1);return 0;
}
#include <bits/stdc++.h>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}cout<<endl;
}
int main()
{vector<int> v1;v1.push_back(10);v1.push_back(20);v1.push_back(30);reverse(v1.begin(),v1.end());print(v1);v1.resize(20);print(v1);return 0;
}
#include <bits/stdc++.h>
using namespace std;void print(vector <int> v)
{for(int i=0; i<v.size(); i++){cout<<v[i]<<" ";}cout<<endl;
}
int main()
{vector<int> v1;v1.push_back(10);v1.push_back(20);v1.push_back(30);reverse(v1.begin(),v1.end());print(v1);v1.resize(2);print(v1);v1.resize(3);print(v1);return 0;
}
初始化二维 vector:vector<vector<int>> v(20);
这创建了一个包含 20 个元素的二维 vector,其中每个元素都是一个空的 vector<int>。
访问内层 vector:当你使用 v[i] 时,你实际上访问的是这个二维 vector 的第 i 个元素。由于二维 vector 已经被初始化,所以这个操作是安全的。
向内层 vector 添加元素:使用 .push_back(i+j) 向第 i 个内层 vector 添加元素。在每次循环中,这个内层 vector 会根据需要增长,因为 vector 是动态数组,它可以根据添加的元素数量自动调整大小。
#include <bits/stdc++.h>
using namespace std;int main()
{//cin cout加速代码 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);//定义二维的vector 因为>>表示右移运算符 vector<vector <int> > v(20);for(int i=0; i<5; i++){for(int j=0; j<5; j++){v[i].push_back(i+j); }} for(int i=0; i<5;i++){for(int j=0; j<5; j++){cout<<v[i][j]<<" ";}cout<<endl;}return 0;
}
定义一个空的二维vector在进行动态增加
#include <iostream>
#include <vector>
using namespace std;int main() {vector<vector<int>> v; // 定义一个空的二维vector// 动态地填充5x5的二维vectorfor (int i = 0; i < 5; i++) {vector<int> row; // 创建一个新行for (int j = 0; j < 5; j++) {row.push_back(i + j); // 向这个新行添加元素}v.push_back(row); // 将新行添加到二维vector中}// 打印二维vector的内容for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {cout << v[i][j] << " ";}cout << endl;}return 0;
}
直接使用vector定义一个二维的vector,竖着输入
在 C++ 中,vector<vector<int>> 是一个二维向量。它可以被视为一个表格,其中每行是一个向量(即一个一维数组)。
初始化: vector<vector<int>> v(n, vector<int>(m));这行代码初始化了一个 n x m 的二维向量,其中每个元素默认为 0。这相当于创建了一个具有 n 行和 m 列的表格。
int n = 5; // 行数
int m = 5; // 列数
vector<vector<int>> v(n, vector<int>(m));
int temp = 0;
for(int i = 0; i < m; ++i) {for(int j = 0; j < n; ++j) {v[j][i] = ++temp;}
}
指针复习:
#include <bits/stdc++.h>
using namespace std;int main()
{//cin cout加速代码 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);char s[] = "hello";char *p = s;for(p=s; *p != '