备战蓝桥杯Day11 DFS
DFS
1.要点
(1)朴素dfs
下面保存现场和恢复现场就是回溯法的思想,用dfs实现,而本质是用递归实现,代码框架:
ans; //答案,常用全局变量表示
int mark[N]; //记录状态i是否被处理过
dfs(层数,其他参数){if(到达目的地,或者出局){ //到达最底层,或者满足条件退出 更新答案 ans; //答案ans一般用全局变量表示 return ; //回溯,返回到上一层,在二叉树中是返回父节点 }//剪枝 //进一步DFS之前剪枝,减少搜索范围 for(用i遍历下一层所有可能的情况) //继续深入 if(mark[i]==0){ //如果状态i没有处理过,就可以进行下一层DFS mark[i]=1; //标记状态i为已经使用,在后续的DFS时不能再使用 dfs(层数+1,其他参数); //下一层,继续深入DFS mark[i]=0; //回复状态i,回溯时不影响上一层对这个状态的使用,难点 }return ; //返回到上一层,可以返回一个结果
}
第10行的mark[i]=1称为“保存现场”。第12行的mark[i]=0称为“恢复现场”。
适合每个状态都是唯一的,不存在重叠子问题,例如:N皇后问题、全排列问题、组合问题、图的遍历问题
(2)记忆化dfs
在朴素dfs的基础上新增了一个记录递归中间状态和数据的容器,难点在于状态数组要记录哪些状态,以及该状态下的什么值
适合存在重叠子问题,例如:斐波那契数列、爬楼梯问题、最长公共子序列、矩阵中的路径问题
(3)剪枝
优化回溯法,先暴力搜索,然后根据关系让搜索变少
2.题目
(1)朴素dfs
1508N皇后
学习:
(1)朴素dfs,考虑搜索深度就是行数,每一行放置皇后的状态是唯一的,不存在重叠子问题,不用记忆化,理解模版
代码:
#include <bits/stdc++.h>using namespace std;const int N=15;
int a[N][N],n,res; //a数组表示是否放置 bool check(int dep,int j){//先看看这一列行不行for(int i=1;i<=n;i++){if(a[i][j]) return false;}//再看左上方和右上方,因为按行搜索,所以下方不可能有 for(int i=dep,k=j;i>=1&&k>=1;i--,k--){ //中间条件用&& if(a[i][k]) return false;}for(int i=dep,k=j;i>=1&&k<=n;i--,k++){if(a[i][k]) return false;}return true;
}//按行数为深度一层层搜素
void dfs(int dep){if(dep==n+1){ //n行搜索完 res++; //是一种情况 return; //回溯 }for(int j=1;j<=n;j++){ //遍历这一行放置在哪里 //能放置,则改变现场并向下搜索 if(check(dep,j)){a[dep][j]=1;//向下一行搜索dfs(dep+1);//恢复现场a[dep][j]=0;} }
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;dfs(1);cout<<res;return 0;
}
2018小朋友崇拜圈
学习:
(1)dfs函数void和int没什么区别,void就是再递归结束条件里面更新ans,而int就是return ans
(2)与上一题不一样,直接dfs(1),因为就是从第一行开始向下搜索,不断搜索,不断回溯,但是这个小朋友崇拜圈是每个小朋友都向下搜索并回溯一次,所有为dfs(i,0)
朴素dfs代码:
#include <bits/stdc++.h>using namespace std;const int N=1e5+10;
int n,a[N],ans;
int t,mark[N];//t为开始的小朋友id,mark数组表明该小朋友是否被遍历过 //当前第id个小朋友,以及之前遍历了cnt个小朋友
void dfs(int id,int cnt){//递归结束条件 if(mark[id]){ //以及遍历过第id个小朋友,可能是圈,也可能不是圈 if(id==t){ //是圈 ans=max(ans,cnt);}return;}mark[id]=1;//第id个小朋友被访问,下面cnt+1 dfs(a[id],cnt+1);mark[id]=0;
}int main(){ios::sync_with_stdio(false);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}for(int i=1;i<=n;i++){t=i;//这边不用写markdfs(i,0);}cout<<ans;return 0;
}
(3)上面dfs存在一个圈每个小朋友都有搜索一次,有重复,利用时间戳优化,时间戳就是每个小朋友第几步被访问到并记录下来,利用之前记录的mindfn(最小时间戳)来判断是不是新的圈
![[小朋友崇拜圈.png]]
时间戳:1 3 2 4 5 6 8 7 9
有时间戳,说明访问过,例如从id=1开始,最小时间戳1,最终从id=5,时间戳为5,到id=3,时间戳为2>1,说明有新的圈,圈长度5-2+1=4.而从id=7,最小时间戳为8开始,到id=4,时间戳为4<8,说明访问之前时间戳的圈的元素,不算.
且在for循环内先判断时间戳是否存在,不存在在dfs,可以优化每个圈只访问1次
代码:
#include <bits/stdc++.h>using namespace std;const int N=1e5+10;
int n,a[N],ans;
int dfn[N],idx;//dfn为每个小朋友的时间戳,表示该小朋友是第几个被访问到的,idx记录当访问序号
int mindfn;//记录当前时间戳,只有大于mindfn,才说明是新的圈,否则访问之前时间戳没用 //当前在第id个小朋友,返回圈的人数
int dfs(int id){dfn[id]=idx++; //更新时间戳//递归出口if(dfn[a[id]]){ //有时间戳,说明访问到之前访问过的小朋友 if(dfn[a[id]]<mindfn) return 0; //访问之前时间戳,不是个圈else return dfn[id]-dfn[a[id]]+1; //访问mindfn之后的时间戳,是新的圈,注意不是减去dfnmin(因为可能不在圈中) }//没有时间戳就向下搜索,递归返回最终结果即可 return dfs(a[id]);}int main(){ios::sync_with_stdio(false);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}idx=1; //从1开始 for(int i=1;i<=n;i++){ //遍历每个小朋友,寻找圈 if(!dfn[i]){ //该小朋友没被访问过,避免一个圈访问多次 mindfn=idx; //改变最小时间戳ans=max(ans,dfs(i)); }} cout<<ans;return 0;
}
(2)连通性
2023最大连通
学习:
(1)最简单常规的一道连通dfs,不过注意题目要求,最后输出答案即可,且输入的0和1是字符数组,不是整数数组(巨坑)!!!
代码:
#include <bits/stdc++.h>using namespace std;int const n=30,m=60;//加const才能编译通过
char a[n][m];//字符数组!!!
int mark[n][m],ans;
int dx[]={0,0,-1,1},dy[]={-1,1,0,0};bool inmap(int x,int y){return 0<=x && x<n && 0<=y && y<m;
}int dfs(int x,int y){if(a[x][y]=='0') return 0; //递归结束条件 mark[x][y]=1;int cnt=1;for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if(!inmap(nx,ny)) continue;if(a[nx][ny]=='1' && !mark[nx][ny]) cnt=cnt+dfs(nx,ny);}return cnt;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>a[i][j];}}for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(a[i][j]=='1' && !mark[i][j]){ans=max(ans,dfs(i,j));}}}ans=148;cout<<ans;return 0;
}
连接草坪(II)
学习:
(1)这道题是dfs的应用,dfs就是给每块草坪(连通块)染上或标号,同时记录同一块草坪里面每个草地的位置坐标,为后续寻找最短路径做准备。
(2)寻找填补多少块土地能把所有连通块连起来,要分情况讨论,情况1是以某块土地到所有草坪路径和最少,情况2为草坪间距离和最少,所有最终答案就取最小的,但是情况1要减2,因为该块土地被计算2次,情况2也要减2,因为两块草坪的草地不算
(3)计算1-2,2-3,3-1时遍历,可以用j=(i+1<=3?i+1:1)
来完美解决3-1问题
(4)vector的push_back换成emplace_back,其他容器的push也换成emplace,可以放进不用人为手动转换成符合类型元素
(5)最小值设置为1000,不要为1e4(double类型),有些编译器会报错
代码:
#include <bits/stdc++.h>using namespace std;typedef pair<int,int> PII;
const int N=55;
char mp[N][N];
int n,m,ans;
int mark[N][N],cid; //给同一块草坪染上同一个颜色,等同于标号
vector<PII> v[4]; //记录同一颜色草坪的位置坐标
int dx[]={0,0,-1,1},dy[]={-1,1,0,0};bool inmap(int x,int y){return 0<=x && x<n && 0<=y && y<m;
}void dfs(int x,int y,int c){ //dfs给同一块草坪染上颜色c if(mp[x][y]=='.') return; //递归出口mark[x][y]=c;v[c].emplace_back(x,y); //push_back(make_pair(x,y))要清楚知道存入什么类型,而emplace_back系统判断 for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if(!inmap(nx,ny)) continue;if(mp[nx][ny]=='X' && !mark[nx][ny]) dfs(nx,ny,c);}
}//位置x,y到草坪c的最小曼哈顿距离
int count(int x,int y,int c){int minn=1e4;for(auto a:v[c]){minn=min(minn,abs(x-a.first)+abs(y-a.second));}return minn;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>mp[i][j];}}//先dfs染色 cid=1;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(mp[i][j]=='X' && !mark[i][j]){dfs(i,j,cid);cid++;}}}ans=1000; //枚举每块地,寻找土地到3块草坪的最短路径和for(int i=0;i<n;i++){for(int j=0;j<m;j++){ if(mp[i][j]=='.'){int cnt=0;for(int k=1;k<=3;k++){cnt+=count(i,j,k);} //3块草坪,最终答案多算了2次土地(i,j) ans=min(ans,cnt-2);}}} //再看草坪到草坪的距离int minn[]={0,1000,1000,1000};//1-2,2-3,3-1for(int i=1;i<=3;i++){int j=(i+1<=3?i+1:1); //巧妙的解决3-1for(auto a:v[i]){minn[i]=min(minn[i],count(a.first,a.second,j));} } for(int i=1;i<=3;i++){ans=min(ans,minn[i]+minn[(i+1<=3?i+1:1)]-2); //这里的减2是减去2块草地,答案只要土地数量 }cout<<ans;return 0;
}
2018全球变暖
学习:
(1)连通块问题,需要开个地图数组以及mark数组记录联通块中每一块是否访问过,保证每个联通块只搜索一次,dfs是void可以没有最终递归条件然后return,函数目的就是更新状态,更新mark数组以及判断该联通块是否会被淹没,更新tag(本质是类似于更新ans)
代码;
#include <bits/stdc++.h>using namespace std;const int N=1e3+10;
char mp[N][N];
int n,ans,mark[N][N],tag;
int dx[]={0,0,-1,1},dy[]={-1,1,0,0};void dfs(int x,int y){mark[x][y]=1; //标记访问过//题目说照片保证第1行、第1列、第N行、第N列的像素都是海洋,不用判断是否会越界,否则正常要判断 if(mp[x][y-1]=='#' && mp[x][y+1]=='#' && mp[x-1][y]=='#' && mp[x+1][y]=='#'){tag=0; //存在一个不会被淹没的陆地,该岛屿不会被完全淹没 } //继续dfs,目的是标记联通块和判断是否会被淹没for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];//同上,不用判断地图越界if(mp[nx][ny]=='#' && !mark[nx][ny]) dfs(nx,ny); //是陆地且未访问过继续搜索 }
} int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>mp[i][j];}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){tag=1; //tag标记是否会被完全淹没 if(mp[i][j]=='#' && !mark[i][j]){ //是陆地且未被访问过才搜索,保证一个联通块岛屿只搜素一次 dfs(i,j);if(tag) ans++; //被完全淹没岛屿加1 }}}cout<<ans;return 0;
}
(3)记忆化
3820混境之地5
学习:
为矩阵中的路径问题,可以记忆化dfs
(1)地图搜索,一般从1开始,构造个方向数组,遍历四个方向即可,再写个判断函数是否不在地图,得到新位置优先判断是否在地图中
int dx[]={0,0,-1,1},dy[]={-1,1,0,0}; //方向数组,学习for(int i=0;i<4;i++){ //开始四个方向搜索 int nx=x+dx[i],ny=y+dy[i]; //x,y为传入的当前位置,nx,ny为目标位置if(!inmap[nx][ny]) continue; //先判断目标搜索位置在不在地图里面,不在直接换方向
代码:
(1)暴力DFS,没有记忆化记录,四个方向都深入到底,这题也能得满分
#include <bits/stdc++.h>using namespace std;
const int N=1e3+10;
int n,m,k,sx,sy,ex,ey,h[N][N]; //sx,sy为开始位置,ex,ey为出口,h数组记录高度
int dx[]={0,0,-1,1},dy[]={-1,1,0,0}; //方向数组,学习bool inmap(int x,int y){ //是否在地图中return 1<=x && x<=n && 1<=y && y<=m;
}bool dfs(int x,int y,int t){ //当前位置和使用喷漆背包次数 if(x==ex && y==ey) return true; //先写最终情况for(int i=0;i<4;i++){ //开始四个方向搜索 int nx=x+dx[i],ny=y+dy[i];if(!inmap(nx,ny)) continue; //先判断目标搜索位置在不在地图里面,不在直接换方向 //没用过喷漆背包 if(t==0){//使用喷漆背包,说明当前位置高度+喷漆背包能提升高度>=目标位置高度,没有记忆化记录数组就是再判断dfs(nx,ny,t+1) if(h[x][y]+k>=h[nx][ny] && dfs(nx,ny,t+1)){return true;}//不用喷漆背包else if(h[x][y]>h[nx][ny] && dfs(nx,ny,t)){return true;}}//用过喷漆背包,不能使用else{if(h[x][y]>h[nx][ny] && dfs(nx,ny,t)){return true;}} } //在当前位置四个方向都无法前进且当前位置不在终点,说明不能到达return false;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m>>k>>sx>>sy>>ex>>ey;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>h[i][j];}}cout<<(dfs(sx,sy,0)?"Yes":"No");return 0;
}
(2)使用记忆化数组dp[x][y][t]
,(不是bool,而是int,因为要赋初值-1判断)表示在x,y位置,背包使用次数t这一状态下是否搜索过该位置且该位置是否能继续搜索下去.初始值-1,表示没有搜索过,若为0,表示搜索过,但无法再往四个方向更深层次搜索,若为1,表示搜索过,且可以往更深层次搜索
int dp[N][N][2]; //记忆化搜索数组 //main中memset初始化
memset(dp,-1,sizeof(dp));//dfs中对dp数组赋值
bool dfs(int x,int y,int t){ //当前位置和使用喷漆背包次数 if(x==ex && y==ey) return true; //先写最终情况if(dp[x][y][t]!=-1) return dp[x][y][t]; //搜索过不再搜索 for(int i=0;i<4;i++){ //开始四个方向搜索 int nx=x+dx[i],ny=y+dy[i];if(!inmap(nx,ny)) continue; //先判断目标搜索位置在不在地图里面,不在直接换方向 //没用过喷漆背包 if(t==0){//使用喷漆背包,说明当前位置高度+喷漆背包能提升高度>=目标位置高度 if(h[x][y]+k>=h[nx][ny] && dfs(nx,ny,t+1)){dp[x][y][t]=true; //记忆化 return true;}//不用喷漆背包else if(h[x][y]>h[nx][ny] && dfs(nx,ny,t)){dp[x][y][t]=true; //记忆化 return true;}}//用过喷漆背包,不使用else{if(h[x][y]>h[nx][ny] && dfs(nx,ny,t)){dp[x][y][t]=true; //记忆化 return true;}} } //在当前位置四个方向都无法前进且当前位置不在终点,说明不能到达dp[x][y][t]=false;//记忆化 return false;
}
2014地宫取宝
要点:
矩阵中的路径问题,可以记忆化dfs
(1)记忆化想好dp数组记录哪些状态,记录的又是什么值,dp数组记录的状态就是dfs函数的参数
#include <bits/stdc++.h>using namespace std;typedef long long ll;
const int N=55,p=1e9+7;
int n,m,k,v[N][N];//v为地图宝贝价值
ll dp[N][N][15][15]; //dp为状态数组,表示在(x,y)位置,宝贝最大值为maxn,宝贝数量为t件这一状态的方案个数
int dx[]={0,1},dy[]={1,0};bool inmap(int x,int y){return 1<=x && x<=n && 1<=y && y<=m;
}//状态为位置(x,y),当前宝贝最大值maxn,宝贝数量cnt
ll dfs(int x,int y,int maxn,int cnt){ if(x==n && y==m) return cnt==k; //最终条件,判断cnt等不等于k,等于才方案数加1 if(dp[x][y][maxn][cnt]!=-1) return dp[x][y][maxn][cnt]; //搜索过了,直接返回方案个数 ll res=0; //从当前位置开始的方案个数for(int i=0;i<2;i++){int nx=x+dx[i],ny=y+dy[i];if(!inmap(nx,ny)) continue;//拿宝贝,说明此地宝贝价值大于当前宝贝最大值且宝贝数量小于k if(v[nx][ny]>maxn && cnt<k){res=(res+dfs(nx,ny,v[nx][ny],cnt+1))%p; //要去余记得每个地方都要取余 }//不拿宝贝 ,说明此地宝贝价值小于当前宝贝最大值或者宝贝数量大于等于k //不能写else,否则对于当前位置,遗漏了以拿但选择不拿的情况,但实际上后面可能有更好的,每个位置都可以不拿宝贝 res=(res+dfs(nx,ny,maxn,cnt))%p; } return dp[x][y][maxn][cnt]=res; //记忆化更新
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);memset(dp,-1,sizeof(dp));cin>>n>>m>>k;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>v[i][j];v[i][j]++;//状态数组宝贝最大值初值为0,不好变为-1,所以把价值整体+1,避免0,不影响方案个数 }}cout<<(dfs(1,1,0,0)+dfs(1,1,v[1][1],1))%p;//在(1,1)两种情况,拿或不拿,两种情况独立相加 return 0;
}
(4)剪枝
数字王国之军训排队
学习:
(1)用一个mark数组来标记该序号的学生是否已经被划分为之前的队伍中,是的话直接dfs下一层,就是剪枝
(2)注意vector<int> v[N]
表示一个大小为N的数组v,里面元素类型为vector<int>
,等同于vector<vector<int>> v
,但是用vector<int> v[N]
更好操作
代码;
#include <bits/stdc++.h>using namespace std;const int N=15;
int a[N],n,ans,mark[N];
vector<int> v[N];//记录每一队里面学生名字,注意这个v数组里面元素类型是vector<int>,v数组大小为N void dfs(int x){//递归出口 if(x==n) return;//剪枝,如果已经在队伍中,直接跳过 if(mark[x]) dfs(x+1);bool t=true;for(auto &i:v[ans]){ //v[ans]为vector<int>,遍历vector<int> if(a[x]%i==0 || i%a[x]==0){t=false;break;}}if(t){mark[x]=1;v[ans].emplace_back(a[x]);}dfs(x+1);
}int main(){ios::sync_with_stdio(false);cin>>n;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<n;i++){if(!mark[i]){dfs(i);ans++;}}cout<<ans;return 0;
}
特殊的多边形
学习:
(1)n边型n条边的排列选择就是dfs递归的层数,通过计算每一条边的上限来进行剪枝,最后利用一下前缀和,不过三角形可以3层暴力枚举,不过枚举范围要开大点
代码:
#include <bits/stdc++.h>using namespace std;typedef long long ll;
const int N=1e5+10;
int t,n;
ll a[N],prefix[N];void dfs(int dep,int st,int mul,int sum){ //dep为层数,就是n边形的边数,st为前一条边长度,mul为乘积,sum为和 //剪枝1if(mul>N) return; //递归出口 if(dep==n+1){a[mul]++;return;}//剪枝2,获取此边上限长度,mul*x^(n-dep+1)<=N,再移项可得,x<=(N/mul)^(1/(n-dep+1)) int up=pow(1.0*N/mul,1.0/(n-dep+1))+3; //得加个数后面,下面为小于up,不然可能最后的值取不到//剪枝3,最后一条边考虑sum,类似于三角形两边之和大于第三边,其余的考虑up for(int i=st+1;i<(dep==n?sum:up);i++){ dfs(dep+1,i,mul*i,sum+i);}
}
int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>t>>n;dfs(1,0,1,0); //从第一层开始,乘积从1开始 for(int i=1;i<=N;i++){prefix[i]=prefix[i-1]+a[i];}for(int i=0;i<t;i++){int l,r;cin>>l>>r;cout<<prefix[r]-prefix[l-1]<<endl;}return 0;
}
数的划分
学习:
(1)跟上面剪枝一样,只不过上面是乘积,这里是和,注意st从1开始
代码:
#include <bits/stdc++.h>using namespace std;int n,k,ans;void dfs(int dep,int st,int sum){ //层数,前一个数,和 if(sum>n) return;if(dep==k+1 && sum<n) return;if(dep==k+1 && sum==n){ans++;return;}//剪枝1,求上限,sum+x*(k-dep+1)<=n,即x<=(n-sum)/(k-dep+1) int up=1.0*(n-sum)/(k-dep+1)+1;for(int i=st;i<up;i++){dfs(dep+1,i,sum+i);}
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>k;dfs(1,1,0);cout<<ans;return 0;
}
相关文章:
备战蓝桥杯Day11 DFS
DFS 1.要点 (1)朴素dfs 下面保存现场和恢复现场就是回溯法的思想,用dfs实现,而本质是用递归实现,代码框架: ans; //答案,常用全局变量表示 int mark[N]; //记录状态i是否被处理过 …...
Oracle 认证为有哪几个技术方向
Oracle 认证技术方向,分别是数据库管理、开发、云平台,每个方向都有不同的学习等级 数据库运维方向 Oracle Certified Professional(OCP):19c OCA内容已和OCP合并 OCP 19c属于oracle认证专家,要求考生掌握深…...
25物理学研究生复试面试问题汇总 物理学专业知识问题很全! 物理学复试全流程攻略 物理学考研复试调剂真题汇总
正在为物理考研复试专业面试发愁的你,是不是不知道从哪开始准备? 学姐告诉你,其实物理考研复试并没有你想象的那么难!只要掌握正确的备考方法,稳扎稳打,你也可以轻松拿下高分!今天给大家准备了…...
网络安全技术与应用
文章详细介绍了网络安全及相关技术,分析了其中的一类应用安全问题——PC机的安全问题,给出了解决这类问题的安全技术——PC防火墙技术。 1 网络安全及相关技术 自20世纪…...
APISIX Dashboard上的配置操作
文章目录 登录配置路由配置消费者创建后端服务项目配置上游再创建一个路由测试 登录 http://192.168.10.101:9000/user/login?redirect%2Fdashboard 根据docker 容器里的指定端口: 配置路由 通过apisix 的API管理接口来创建(此路由,直接…...
深度剖析数据分析职业成长阶梯
一、数据分析岗位剖析 目前,数据分析领域主要有以下几类岗位:业务数据分析师、商业数据分析师、数据运营、数据产品经理、数据工程师、数据科学家等,按照工作侧重点不同,本文将上述岗位分为偏业务和偏技术两大类,并对…...
HarmonyOS学习第11天:布局秘籍RelativeLayout进阶之路
布局基础:RelativeLayout 初印象 在 HarmonyOS 的界面开发中,布局是构建用户界面的关键环节,它决定了各个组件在屏幕上的位置和排列方式。而 RelativeLayout(相对布局)则是其中一种功能强大且灵活的布局方式࿰…...
问题修复-后端返给前端的时间展示错误
问题现象: 后端给前端返回的时间展示有问题。 需要按照yyyy-MM-dd HH:mm:ss 的形式展示 两种办法: 第一种 在实体类的属性上添加JsonFormat注解 第二种(建议使用) 扩展mvc框架中的消息转换器 代码: 因为配置类继…...
怎么排查页面响应慢的问题
一、排查流程图 -----------------| 全局监控报警触发 |-----------------|▼-----------------| 定位异常服务节点 |-----------------|------------------▼ ▼ ----------------- ----------------- | 基础设施层排查 | | 应用层代码排查 | | (网…...
第二十四:5.2【搭建 pinia 环境】axios 异步调用数据
第一步安装:npm install pinia 第二步:操作src/main.ts 改变里面的值的信息: <div class"count"><h2>当前求和为:{{ sum }}</h2><select v-model.number"n"> // .number 这里是…...
SpringBoot——生成Excel文件
在Springboot以及其他的一些项目中,或许我们可能需要将数据查询出来进行生成Excel文件进行数据的展示,或者用于进行邮箱发送进行附件添加 依赖引入 此处demo使用maven依赖进行使用 <dependency><groupId>org.apache.poi</groupId>&…...
java高级(IO流多线程)
file 递归 字符集 编码 乱码gbk,a我m,utf-8 缓冲流 冒泡排序 //冒泡排序 public static void bubbleSort(int[] arr) {int n arr.length;for (int i 0; i < n - 1; i) { // 外层循环控制排序轮数for (int j 0; j < n -i - 1; j) { // 内层循环…...
MySQL 用户权限管理深度解析:从基础到高阶实践(2000字指南)
MySQL 用户权限管理是数据库安全与运维的核心环节。无论是本地开发环境还是企业级生产环境,合理配置用户权限、理解版本差异、遵循安全规范都至关重要。本文将从 基础权限配置、版本差异详解、安全加固策略、高阶权限管理、故障排查 等多个维度展开,覆盖 MySQL 5.7、8.0 …...
【0011】HTML其他文本格式化标签详解(em标签、strong标签、b标签、i标签、sup标签、sub标签......)
如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: 本文旨在深入探讨HTML中其他的文本格式化标签,主要有<em> 标签、<strong> 标签、…...
数据虚拟化的中阶实践:从概念到实现
数据虚拟化的中阶实践:从概念到实现 在大数据时代,数据的数量、种类和来源呈现爆炸式增长,如何高效、灵活地访问和利用这些数据成为了企业面临的重要问题。数据虚拟化作为一种创新的技术,正逐渐成为解决这一难题的关键。它通过抽象化层将底层数据源与应用程序隔离,使得数…...
AI辅助学习vue第十四章
第十四章:技术引领与未来展望 在第十五章,你已经在Vue技术领域深耕许久,积累了丰富的经验与卓越的影响力。此时,你将站在行业前沿,引领技术走向,为Vue技术的未来发展开辟新道路。 1. 引领Vue技术发展方向…...
DeepEP库开源啦!DeepSeek优化GPU通信,破算力瓶颈。
在人工智能和大数据日益盛行的今天,算力成为了制约技术发展的关键因素之一。随着模型规模的不断扩大,GPU间的通信瓶颈问题日益凸显,成为了制约深度学习训练效率的一大难题。近日,DeepSeek团队开源了DeepEP库,旨在通过优…...
蓝桥杯web第三天
展开扇子题目, #box:hover #item1 { transform:rotate(-60deg); } 当悬浮在父盒子,子元素旋转 webkit display: -webkit-box:将元素设置为弹性伸缩盒子模型。-webkit-box-orient: vertical:设置伸缩盒子的子元素排列方…...
Gin从入门到精通 (七)文件上传和下载
文件上传和下载 1.文件上传 1.1单文件上传 在 Gin 中处理单文件上传,可以使用 c.FormFile 方法获取上传的文件,然后使用 c.SaveUploadedFile 方法保存文件。 package mainimport ("github.com/gin-gonic/gin""log" )func main()…...
【Java】Stream API
概述 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。 Stream是Java8中处理集合的关键抽象概念&#…...
linux-Dockerfile及docker-compose.yml相关字段用途
文章目录 计算机系统5G云计算LINUX Dockerfile及docker-conpose.yml相关字段用途一、Dockerfile1、基础指令2、.高级指令3、多阶段构建指令 二、Docker-Compose.yml1、服务定义(services)2、高级服务配置3、网络配置 (networks)4、卷配置 (volumes)5、扩…...
基于Selenium的Python淘宝评论爬取教程
文章目录 前言1. 环境准备安装 Python:安装 Selenium:下载浏览器驱动: 2. 实现思路3. 代码实现4. 代码解释5. 注意事项 前言 以下是一个基于 Selenium 的 Python 淘宝评论爬取教程,需要注意的是,爬取网站数据应当遵守…...
网络空间安全(7)攻防环境搭建
一、搭建前的准备 硬件资源:至少需要两台计算机,一台作为攻击机,用于执行攻击操作;另一台作为靶机,作为被攻击的目标。 软件资源: 操作系统:如Windows、Linux等,用于安装在攻击机和…...
【Veristand】Veristand 预编写教程目录
很久没有更新,最近打算出一期Veristand教程,暂时目录列成下面这个表格,如果各位有关心的遗漏的点,可以在评论区提问,我后期可以考虑添加进去,但是提前声明,太过小众的点我不会,欢迎各…...
大白话页面加载速度,如何优化提升?
大白话页面加载速度,如何优化提升? 咱来好好唠唠页面加载速度这事儿,再说说怎么把它提上去。 页面加载速度是咋回事儿 页面加载速度啊,就好比你去餐厅吃饭,从你坐下点餐到饭菜端上桌的时间。在网页里,就…...
PyCharm 环境配置精髓:打造高效 Python 开发的基石
PyCharm 环境配置精髓:打造高效 Python 开发的基石 在现代软件开发的浪潮中,Python 语言以其简洁、高效和强大的生态系统,成为了众多开发者和企业的首选。而 PyCharm,作为 JetBrains 倾力打造的专业 Python IDE,更是凭借其智能的代码辅助、强大的调试功能和丰富的插件生态…...
通过百度构建一个智能体
通过百度构建一个智能体 直接可用,我不吝啬算力 首先部署一个模型,我们选用deepseek14 构建智能体思考步骤,甚至多智能体; from openai import OpenAIclass Agent:def __init__(self, api_key, base_url, model...
【Maui】自定义统一色彩样式
文章目录 前言一、问题描述二、解决方案三、软件开发(源码)3.1 消息扩展库3.2 样式的使用 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI,可…...
Swan 表达式 - 选择表达式
ANSYS Swan 表达式支持选择(selection)表达式 case, if/then/else。选择表达式根据特定的条件选择不同的分支流。 if/then/else 表达式 if/then/else 表达式的文法如下 if expr then expr else expr 其中,首个expr 的布尔表达式,若其为 true, 则返回 …...
关于深度学习的一份介绍
在这篇文章中,我将介绍有关深度学习的东西,主要是它与神经网络的关系、目前主要的网络有哪些,以及加深神经网络的意义等。 一、联系 在之前的文章中,我曾介绍过神经网络,而所谓的神经网络其实就是深度学习的一种架构…...
JAVA安全—手搓内存马
前言 最近在学这个内存马,就做一个记录,说实话这个内存马还是有点难度的。 什么是内存马 首先什么是内存马呢,顾名思义就是把木马打进内存中。传统的webshell一旦把文件删除就断开连接了,而Java内存马则不同,它将恶…...
SpringMVC(2)传递JSON、 从url中获取参数、上传文件、cookie 、session
一。//传递JSON RequestMapping("/r7")//RequestBody请求 public String r7(RequestBody UserInto user){ return "接收:"user.toString(); } 也可以: 二. //从url中获取参数 RequestMapping("/article/{t}/{articId}&qu…...
unity和unity hub关系
unity和unity hub关系 Unity和Unity Hub是紧密相关但功能不同的两个软件,以下是它们的关系说明: Unity 定义:是一款专业的实时3D开发平台,广泛用于创建各种类型的3D和2D互动内容,如视频游戏、建筑可视化、汽车设计展示、虚拟现实(VR)和增强现实(AR)应用等。功能:提供…...
机器学习:监督学习、无监督学习和强化学习
机器学习(Machine Learning, ML)是人工智能(AI)的一个分支,它使计算机能够从数据中学习,并在没有明确编程的情况下执行任务。机器学习的核心思想是使用算法分析数据,识别模式,并做出…...
DeepSeek-V3:AI语言模型的高效训练与推理之路
参考:【论文学习】DeepSeek-V3 全文翻译 在人工智能领域,语言模型的发展日新月异。从早期的简单模型到如今拥有数千亿参数的巨无霸模型,技术的进步令人瞩目。然而,随着模型规模的不断扩大,训练成本和推理效率成为了摆在…...
计算机毕设-基于springboot的社团管理系统的设计与实现(附源码+lw+ppt+开题报告)
博主介绍:✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围:Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…...
[IP] DDR_FIFO(DDR3 用户FIFO接口)
IP(DDR_FIFO)将DDR3 IP的用户侧复杂接口修改为简易的FIFO接口,用户侧更加简易例化使用MIG 核 IP介绍 c0_xx (连接DDR app接口) 此IP 仅需根据MIG配置进行有限修改,即可使用! 关于IP详细使用说明,参考IP datasheet! 示…...
第 11 章:当代定价问题总结
本章重点讨论了商品化(Commoditization)、折扣对利润的影响、价格战(Price Wars)及超级竞争(Hypercompetition),并提供了相应的应对策略。 1. 商品化(Commoditization) …...
基于ssm的校园跑腿管理系统+vue
作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统共有管理员、用户两个角色 管理员主要的功能用户信息管理、任务信息管理、任务类型管理、接单信息管理、公告信息管理、投诉信息管理、公告类型管…...
36. Spring Boot 2.1.3.RELEASE 中实现监控信息可视化并添加邮件报警功能
1. 创建 Spring Boot Admin Server 项目 1.1 添加依赖 在 pom.xml 中添加 Spring Boot Admin Server 和邮件相关依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-w…...
C# WinForm程序中如何调试dll接口
公司的SF系统是自主开发的。不同的机种会有不同数据记录保存的需求,尤其是客户SQE更是各种奇思妙想......于是做了一个接口,实践之下效果还不错呢。 每每总是忘记怎么调试接口,特记录下备查。首先要将, 1 DLL项目与WinForms项目…...
SslConnection::SslConnection()详解
一、🔍 SslConnection::SslConnection() 详解 这个构造函数的主要作用是: 创建 SSL 对象创建 BIO(I/O 缓冲区)初始化 SSL 服务器模式绑定回调函数(onRead() 处理接收数据) 📌 1. 初始化 SSL 相…...
I2C驱动(九) -- i2c_adapter控制器驱动框架编写
相关文章 I2C驱动(一) – I2C协议 I2C驱动(二) – SMBus协议 I2C驱动(三) – 驱动中的几个重要结构 I2C驱动(四) – I2C-Tools介绍 I2C驱动(五) – 通用驱动i2c-dev.c分析 I2C驱动(六) – I2C驱动程序模型 I2C驱动(七) – 编写I2C设备驱动之i2c_driver I2C驱动(八) – 编写I2C…...
计算机等级考试
一、计算机等级考试——标准评分 (1)选择题 (2)基本操作题 (3)上网题 (4)文字题 (5)表格题 (6)演示文稿 总分:97 满分&…...
cuda-12.4.0 devel docker 中源码安装 OpenAI triton
1,准备 docker 容器 下载docker image: $ sudo docker pull nvidia/cuda:12.6.2-devel-ubuntu20.04 创建容器: sudo docker run --gpus all -it --name cuda_LHL_01 -v /home/hongleili/ex_triton/tmp1:/root/ex_triton/tmp1 nvidia/cuda:12.6…...
软件测试中的BUG
文章目录 软件测试的生命周期BugBug 的概念描述 Bug 的要素案例Bug 级别Bug 的生命周期与开发产生争执怎么办?【高频面试题】先检查自身,Bug 是否描述的不清楚站在用户角度考虑并抛出问题Bug 的定级要有理有据提⾼自身技术和业务水平,做到不仅…...
【Uniapp-Vue3】开发userStore用户所需的相关操作
在项目根路径下创建的stores文件夹中创建user.js文件 并将以下内容复制到user.js中 import {ref} from "vue" import { defineStore } from pinia; const uniIdCo uniCloud.importObject("uni-id-co") const db uniCloud.database(); const usersTable…...
控制kinova机械臂沿给定的末端轨迹运动
一、背景 我们通过不同的方法规划出一条轨迹后,需要验证是否可以让机械臂执行,因此需要将生成的一个一个坐标点发给机械臂,下面记录一下控制kinova机械臂沿给定的末端轨迹运动的方法。 写在前面: a、重新创建了包含kinova官方ro…...
【计网】计算机网络概述
第一章 计算机网络概述 1.2 因特网概述1.2.1 网络、互联网和因特网1.2.2 因特网发展的三个阶段1.2.3 因特网的标准化工作1.2.4 因特网的组成 1.3 三种交换方式1.3.1 电路交换1.3.2 分组交换1.3.3 报文交换1.3.4 三种交换的对比 1.4 计网的定义与分类1.4.1 定义1.4.2 分类 1.5 计…...
docker和containerd从TLS harbor拉取镜像
私有镜像仓库配置了自签名证书,https访问,好处是不需要处理免费证书和付费证书带来的证书文件变更,证书文件变更后需要重启服务,自签名证书需要将一套客户端证书存放在/etc/docker/cert.d目录下,或者/etc/containerd/c…...