C++知识点总结(36-39):深度优先搜索算法综合练习

深度优先搜索算法练习

  • 一、递归
    • 1. 变化的数
    • 2. 数字分解
  • 二、DFS
    • 1. 八个方向的迷宫
    • 2. n 皇后
    • 3. 玩具蛇
    • 4. 深度优先搜索顺序
    • 5. 单词消消乐
    • 6. 奇怪的系统
    • 7. [USACO23JAN] Air Cownditioning II B
  • 三、排列组合
    • 选择同学
  • 四、剪枝优化
    • 1. 走迷宫
    • 2. 危险的工作
    • 3. 规定时间走迷宫

*本篇文章涉及较多知识点,可以在下面查看对应的教程:
递归基础 / 递归进阶 / 递归练习1 / 递归练习2 / DFS1 / DFS2 / 回溯算法 / DFS3

一、递归

1. 变化的数

有一个数 a a a,想把这个数变成 b b b,为此可以做两种变换:

x x x 变为 2 x 2x 2x
x x x 变为 10 x + 1 10x+1 10x+1
例如:2 -> 4 -> 8 -> 81 -> 162

你需要判断一下,把 a a a 变成 b b b 的是否可能,可能则输出 YES,否则输出 NO

#include <iostream>
using namespace std;// 递归判断是否存在变换路径
bool transform(int a, int b)
{if (a == b) return 1; // 当 a 和 b 相等时,变换成功,返回 trueif (a > b) return 0; // 当 a 大于 b 时,无法变换,返回 falsereturn transform(a*2, b) || transform(a*10+1, b); // 递归进行两种变换判断
}int main()
{int a, b;cin >> a >> b;cout << (transform(a, b) ? "YES" : "NO"); // 输出是否存在变换路径return 0;
}

2. 数字分解

一个正整数,可以分解成多个大于等于 1 1 1 的整数之和的形式,要求这些数字从左向右是递增的(即后一个数小于等于前一个数)。请你求出对于一个整数 n n n,一共有多少种分解方案。

#include <iostream>
using namespace std;int n;int f(int n, int maxn)
{if (n == 0) return 1;int cnt = 0;for (int i = 1; i <= maxn && i <= n; i++){cnt += f(n-i, i);}return cnt;
}int main()
{cin >> n;cout << f(n, n);
}

二、DFS

1. 八个方向的迷宫

给定一个 n n n m m m 列的迷宫,有些格子可以走,有些有障碍物不能到达。每步可以走到周围 8 8 8 个方向的格子中。请你判断,是否能从左上角走到右下角。如果能走到输出 YES,否则输出 NO

同样地,不撞南墙不回头,记得将偏差值改一下就好了。

#include <iostream>
#include <cstdio>
using namespace std;int n, m; // 迷宫大小
bool flag; // 是否有解 
char Map[25][25]; // 地形图
bool vis[25][25]; // 标记是否走过 
int dx[10] = {-1, -1, -1, 0, 0, 1, 1, 1}; // 八个方向的偏移量 
int dy[10] = {-1, 0, 1, -1, 1, -1, 0, 1}; // 八个方向的偏移量 void dfs(int x, int y)
{// 到终点 if (x == n && y == m){flag = true;return;}// 遍历方向,判断是否满足条件for (int i = 0; i < 8; i++){int tmpX = x + dx[i];int tmpY = y + dy[i];// 是通路if (Map[tmpX][tmpY] == '.'){// 未到边界if (tmpX >= 1 && tmpX <= n && tmpY >= 1 && tmpY <= m) {// 未访问if (vis[tmpX][tmpY] == false) {vis[tmpX][tmpY] = true;dfs(tmpX, tmpY);}}}}
}int main()
{freopen("map.in", "r", stdin);freopen("map.out", "w", stdout);// 输入cin >> n >> m;for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cin >> Map[i][j];}}// dfsvis[1][1] = 1;dfs(1, 1);// 输出	cout << (flag ? "YES" : "NO");fclose(stdin);fclose(stdout);return 0;
}

2. n 皇后

题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n n n 皇后问题研究的是如何将 n n n 个皇后放置在 n × n n\times n n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n n n,求出所有不同的 n n n 皇后问题的解决方案。
每一种解法包含一个不同的 n n n 皇后问题的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

输入描述

仅一行,一个正整数 n n n

输出描述

若干行, n × n n\times n n×n 的棋盘所有的解,每个解用空格隔开

样例1

输入

4

输出

.Q..
...Q
Q...
..Q...Q.
Q...
...Q
.Q..

提示

4 ≤ n ≤ 18 4≤n≤18 4n18

思路:这是根据《C++知识点总结(37):回溯算法》中第四节的题目改编而来。我们可以知道,按照题目所描述的方法,我们应该使得:

  • 每一行都只有一个皇后
  • 每一列都只有一个皇后
  • 每一个正对角线都只有一个皇后
  • 每一个负对角线都只有一个皇后
#include <iostream>
using namespace std;int n;
bool a[20][20];
bool row[20];
bool col[20];
bool zd[40], fd[40];void dfs(int r)
{if (r > n){for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){if (a[i][j]){cout << "Q";}else{cout << ".";}}cout << endl;}cout << endl;return;}for (int j = 1; j <= n; j++) // 遍历每个列{if (!a[r][j] && !row[r] && !col[j] && !zd[r+j] && !fd[r-j+n]) // 是否没有冲突{a[r][j] = true;row[r] = true;col[j] = true;zd[r+j] = true;fd[r-j+n] = true;dfs(r+1);a[r][j] = false;row[r] = false;col[j] = false;zd[r+j] = false;fd[r-j+n] = false;}}
}int main()
{cin >> n;dfs(1);return 0;
}

3. 玩具蛇

题目描述

小蓝有一条玩具蛇,一共有 n 2 n^2 n2 节,上面标着数字1至 n 2 n^2 n2,每一节都是一个正方形的形状,相邻的两节可以成直线或者成直角。
小蓝还有一个 n × n n\times n n×n 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母共 n 2 n^2 n2 个字母。
小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。
请帮小蓝计算一下,总共有多少种不同的方案。如果存在玩具蛇的某一节放在了盒子的不同格子里,则认为是不同的方案。

输入描述

一个整数 q q q,表示输入 q q q 组方格盒子。
接下来 q q q 行,每行代表一个 n × n n\times n n×n 的方格盒子。

输出描述

q q q 个整数表示每个方格盒子的方案数。

样例1

输入

2
2
4

输出

8
552

提示

1 ≤ n ≤ 5 1\le n\le5 1n5

#include <iostream>
#include <cstring>
using namespace std;int q; // 输入的组数
int n; // 盒子的边长
bool vis[10][10]; // 盒子是否被占据
int total; // 方案数量
int dx[5] = {-1, 0, 1, 0};
int dy[5] = {0, 1, 0, -1};void dfs(int x, int y, int cnt)
{if (cnt == n*n){total++;return;}for (int i = 0; i < 4; i++){int tx = x+dx[i];int ty = y+dy[i];if (tx>=1 && tx<=n && ty>=1 && ty<=n){if (vis[tx][ty] == 0){vis[tx][ty] = 1;dfs(tx, ty, cnt+1);vis[tx][ty] = 0;}}}
}int main()
{// 输入cin >> q;for (int i = 1; i <= q; i++){cin >> n;total = 0;memset(vis, 0, sizeof(vis));// dfsfor (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){vis[i][j] = 1;dfs(i, j, 1);vis[i][j] = 0;}}// 输出cout << total << endl;}return 0;
}

4. 深度优先搜索顺序

题目描述

给定一个 n n n m m m 列的迷宫,有些格子可以走,有些有障碍物不能到达。每步可以走到上下左右的格子中。请你输出从左上角(第一行第一列)开始深度优先搜索所有格子的顺序。其中,从一个格子出发,优先出发的顺序为:上、下、左、右,每个格子只遍历一次,即按搜索顺序输出从左上角开始能够搜索到的所有位置。

输入描述

第一行有两个正整数 n n n m m m,表示迷宫的行数和列数。
接下来 n n n 行为输入这个迷宫,每行为一个长度为 m m m 的字符串。第 i i i 行第 j j j 列的字符为 '*' 表示迷宫第 i i i 行第 j j j 列的格子有障碍物,为 '.' 表示没有障碍物。

输出描述

若干行,按遍历顺序在每行输出搜索到的格子。第 x x x 行第 y y y 列的格子以 "(x,y)" 的格式输出。

样例1

输入

3 3
.*.
...
***

输出

(1,1)
(2,1)
(2,2)
(2,3)
(1,3)

提示

1 ≤ n , m ≤ 100 1 \le n, m \le 100 1n,m100

#include <iostream>
using namespace std;int n, m;
char a[105][105];
bool vis[105][105];
int dx[5] = {-1, 1, 0, 0};
int dy[5] = {0, 0, -1, 1};
int pos = 1;
int ansx[10005];
int ansy[10005];void dfs(int x, int y)
{cout << "(" << x << "," << y << ")\n";for (int i = 0; i <= 3; i++){int tx = x+dx[i];int ty = y+dy[i];if (a[tx][ty] == '.'){if(tx>=1 && tx<=n && ty>=1 && ty<=m){if (vis[tx][ty] == 0){vis[tx][ty] = 1;dfs(tx,ty);}}}}
}int main()
{// 输入cin >> n >> m;for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cin >> a[i][j];}}// dfsvis[1][1] = 1;dfs(1, 1);return 0;
}

5. 单词消消乐

题目描述

给定一个 n × n n \times n n×n 的字母方阵和一个字符串单词,内可能含有多个这样的单词,单词在方阵中是沿着同一方向连续摆放的,摆放可沿着 8 8 8 个方向的任一方向,同一单词摆放时不再改变单词方向,单词与单词之间可以交叉,因此可能共用字母,输出时,将不是单词的字母用 '*' 代替,以凸显单词。

输入描述

输入文件名word.in。
第一行一个数 n n n,表示字母方阵的大小( 7 ≤ n ≤ 100 7 \le n \le 100 7n100),第二行开始输入 n × n n \times n n×n 的字母方阵,字母间没有空格。
最后一行输入一个字符串单词,单词长度在 1 1 1 15 15 15 之间。

输出描述

输出文件名word.out。
突出显示单词的 n × n n \times n n×n 字母方阵。

样例1

输入

4
abcd
fesh
eawj
qbso
ab

输出

ab**
****
*a**
*b**

提示

题中所有字母均为小写

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;int n;
int pos;
char a[120][120];
int dx[10] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[10] = {-1, 0, 1, -1, 1, -1, 0, 1};
string s;
int px[120], py[120];
bool vis[120][120];void dfs(int x, int y, int h)
{if (pos == s.length()) // 边界{for (int i = 0; i < pos; i++){vis[px[i]][py[i]] = 1;}return;}int tx = x + dx[h];int ty = y + dy[h];if (tx >= 1 && tx <= n && ty >= 1 && ty <= n && a[tx][ty] == s[pos]){px[pos] = tx;py[pos] = ty;pos++;dfs(tx, ty, h);}
}int main()
{freopen("word.in", "r", stdin);freopen("word.out", "w", stdout);// 输入cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){cin >> a[i][j];}}cin >> s;// 找到开头字符for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){if (a[i][j] == s[0]){for (int h = 0; h <= 7; h++){pos = 0;// memset(px, 0, sizeof(px));// memset(py, 0, sizeof(py));px[0] = i;py[0] = j;pos++;dfs(i, j, h);}}}}// 输出for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){if (vis[i][j]){cout << a[i][j];}else{cout << "*";}}cout << endl;}fclose(stdin);fclose(stdout);return 0;
}

6. 奇怪的系统

题目描述

原本平静的生活被打破,你被卷入一场神秘的案件中,成为侦探团的一员,由于你自带解谜系统,所以解决案件对你来说小菜一碟,但系统有一个神奇的地方,只有给出满足要求的案件物品,系统才能给出线索,每个案件物品都有线索值,因此组合得到的线索也不一样。
现在你面前有 n n n 个不同线索值的案件物品,系统需要的线索值为 m m m,每给出一组不同的物品组合使线索值总和刚好为 m m m 则可以得到一条新的线索,并且物品不会因为给系统而消失,为了解开这个谜团,你需要选择合适数量与线索值的案件物品给系统,以此得到不同的线索,你一共能够得到多少条线索呢?

输入描述

第一行输入 n n n m m m,第二行一共 n n n 个数字,表示每个案件物品的线索值 a i a_i ai

输出描述

输出能够得到的线索条数。

样例1

输入

3 40 
20 20 20

输出

3

提示

【样例解释】
一共 3 3 3 个物品,线索值分别为 20 , 20 , 20 20,20,20 20,20,20
系统需要的线索值为 40 40 40,则可以 1 , 2 1,2 1,2 组合, 1 , 3 1,3 1,3 组合, 2 , 3 2,3 2,3 组合刚好都为 40 40 40 1 , 2 , 3 1,2,3 1,2,3 组合超过 40 40 40 不符合,所以得到 3 3 3 条线索。
【数据范围】
0 < m ≤ 100 , 1 ≤ n ≤ 20 , a i ≤ m 0<m\le100,1\le n\le20,a_i\le m 0<m1001n20aim

#include <iostream>
using namespace std;int n, m;
int cnt;
int a[25];
bool used[25];// 判断选择的数字之和是否等于预设值
bool check()
{// 求和 int sum = 0;for (int i = 1; i <= n; i++){if (used[i]){sum += a[i];}}// 判断是否等于预设值if (sum == m){return true;}return false;
}// pos: 当前位置
// cnt: 选的数字个数 
void dfs(int pos)
{if (pos > n) // 边界{if (check()) // 题目条件{cnt++;}return;}dfs(pos+1); // 不选used[pos] = 1; // 标记dfs(pos+1); // 选 used[pos] = 0; // 回溯
}int main()
{// 输入 cin >> n >> m;for (int i = 1; i <= n; i++){cin >> a[i];}// dfsdfs(1);// 输出cout << cnt; return 0;
}

7. [USACO23JAN] Air Cownditioning II B

参观一下某谷吧。

#include <iostream>
using namespace std;int n, m, k;
int ans = 1e9;
int cw[105], s[25], t[25], c[25], a[25], b[25], p[25], v[25];bool check() // 是否满足条件
{for(int i = 1; i <= k; i++){if (cw[i] > 0){return false;}}return true;
}void dfs(int pos, int s)
{if (pos > m){if (check()){ans = min(ans, s);//满足条件,更新答案}return;}dfs(pos+1, s); // 不选// 标记for(int i = a[pos]; i <= b[pos]; i++)cw[i] -= p[pos];dfs(pos+1, s+v[pos]); // 选// 回溯for(int i = a[pos]; i <= b[pos]; i++)cw[i] += p[pos];
}int main()
{// 输入cin >> n >> m;for(int i = 1; i <= n; i++){cin >> s[i] >> t[i] >> c[i];k = max(k, t[i]);for (int j = s[i]; j <= t[i]; j++){cw[j] += c[i]; //事先处理}}for (int i = 1; i <= m; i++)cin >> a[i] >> b[i] >> p[i] >> v[i];// dfsdfs(1, 0);// 输出cout << ans;return 0;
}

三、排列组合

选择同学

题目描述

今有 n n n 位同学,可以从中选出任意名同学参加合唱。
请输出所有可能的选择方案。

输入描述

仅一行,一个正整数 n n n

输出描述

若干行,每行表示一个选择方案。
每一种选择方案用一个字符串表示,其中第 i i i 位为 Y Y Y 则表示第 i i i 名同学参加合唱;为 N N N 则表示不参加。

样例1

输入

3

输出

NNN
NNY
NYN
NYY
YNN
YNY
YYN
YYY

提示

1 ≤ n ≤ 10 1≤n≤10 1n10

思路:这是非常典型的一道回溯题,与《C++知识点总结(37):回溯算法》中第二节的第一小节比较类似。因为这道题目只有 Y Y Y N N N 两种可能,所以在深度优先搜索的时候,我们只需要用两个递归就可以,不需要 for 循环了。

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;int n;
string s;void dfs(int pos, string s)
{if (pos > n){cout << s << endl;return;}dfs(pos+1, s+'N');dfs(pos+1, s+'Y');
}int main()
{cin >> n;dfs(1, s);return 0;
}

四、剪枝优化

1. 走迷宫

题目描述

在一个神秘的迷宫中,有一个勇敢的冒险家,他的目标是从起点 ( 1 , 1 ) (1,1) (1,1) 走到终点 ( n , n ) (n,n) (n,n)。但是,这个迷宫并不是那么容易通过的,有些地方是可以走的,有些地方是恶龙所在的区域。为了成功通过迷宫,冒险家必须遵循以下规则:

  1. 只能向下、右两个方向移动;
  2. 在移动过程中,可以至多转向 k k k 次。
    如果一条路线中冒险家经过了某个方格而另一条路线中没有,则认为这两条路线不同。
    现在,你需要帮助这位勇敢的冒险家,计算他从起点到终点的方案数。

输入描述

输入文件名maze.in。
第一行包含三个整数 n , k , m n,k,m n,k,m,表示矩阵的大小,转向次数和障碍物的数量。
接下来 m m m 行,每行包含两个整数 x x x y y y,表示第 x x x 行第 y y y 列是障碍物。

输出描述

输出文件名maze.out。
输出一个整数,表示从起点到终点的方案数,方案数可能为 0 0 0那就算给恶龙饱餐一顿了 )。

样例1

输入

5 2 2
2 2
3 4

输出

4

提示

1 ≤ n ≤ 50 1 \leq n \leq 50 1n50
1 ≤ k ≤ 5 1 \leq k \leq 5 1k5
1 ≤ m ≤ 100 1 \leq m \leq 100 1m100

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;int n, k, m;
int cnt;
bool a[60][60];
int dx[5] = {0, 1};
int dy[5] = {1, 0};void dfs(int x, int y, int turn, int direc)
{if (x == n && y == n) // 到达终点 {if (turn <= k){cnt++;}return;}// 剪枝 if (turn > k){return;}if (turn == k){if (x != n && y != n){return;}}// 递归 for (int i = 0; i <= 1; i++){int tx = x + dx[i];int ty = y + dy[i];// 是通路if (a[tx][ty] == 1){// 未到边界if (tx >= 1 && tx <= n && ty >= 1 && ty <= n) {// 是否转弯 if (i != direc && direc != -1){dfs(tx, ty, turn+1, i);}else{dfs(tx, ty, turn, i);}}}}
}int main()
{freopen("maze.in", "r", stdin);freopen("maze.out", "w", stdout);// 初始化迷宫(默认都是通路)memset(a, 1, sizeof(a));// 输入cin >> n >> k >> m;for (int i = 1; i <= m; i++){int x, y;cin >> x >> y;a[x][y] = 0;}// dfsdfs(1, 1, 0, -1);cout << cnt;fclose(stdin);fclose(stdout);return 0;
}

2. 危险的工作

题目描述

在一个神秘的岛屿上,有 N N N 个勇士需要分担 N N N 个危险的工作。每个勇士都有自己的特长,可以担任其中一项工作。每个工作都有一个危险值,代表完成这项工作的风险程度。每个勇士担任工作时,会承担该工作的危险值。现在,你需要为这些勇士分配工作,使得每个勇士承担的危险值之和最小。

输入描述

第一行输入一个整数 N N N,代表勇士的数量。
接下来 N N N 行,每行输入 N N N 个整数,第 i i i 行的 N N N 个数字分别代表第 i i i 个勇士担任 1 − N 1-N 1N 项工作的危险值,用空格隔开。

输出描述

输出一个整数,代表每个勇士承担的危险值之和的最小值。

样例1

输入

3
1 2 3
4 5 6
7 8 9

输出

15

提示

1 ≤ N ≤ 11 1 \le N \le 11 1N11
1 ≤ 1 \le 1 危险值 ≤ 100 \le 100 100

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;int n;
int d[20][20];
int mind = 1e8;
int a[20];
bool vis[20];void dfs(int pos, int total)
{if (pos > n) // 边界{mind = min(mind, total);return;}for (int i = 1; i <= n; i++){if (!vis[i]) // 检查位置是否被占用{vis[i] = true;a[pos] = i; // 标记int new_total = total + d[pos][i];if (new_total <= mind) // 剪枝dfs(pos + 1, new_total); // 递归下一个位置a[pos] = -1; // 回溯vis[i] = false;}}
}int main()
{// 初始化memset(a, -1, sizeof(a));memset(vis, false, sizeof(vis));// 输入cin >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)cin >> d[i][j];// dfsdfs(1, 0);// 输出cout << mind;return 0;
}

3. 规定时间走迷宫

第一行给定迷宫的大小 n , m n,m n,m 和规定时间 t t t,表示有一个 n × m n\times m n×m 的迷宫,起点到终点正好是规定时间(每向某个方向走一格,就算 1 s 1s 1s)。
接下来 n n n 行每行 m m m 个空格隔开的字符,'.' 代表空地,'*' 代表障碍。
最后一行给定初始位置和终点位置 s x , s y , e x , e y sx,sy,ex,ey sx,sy,ex,ey
求你求出符合规定时间的路径数。
数据范围: 1 ≤ n , m ≤ 100 1\le n,m \le 100 1n,m100

#include <iostream>
#include <cmath>
using namespace std;int n, m, t, sx, sy, ex, ey, cnt;
char a[105][105];
bool vis[105][105];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};void dfs(int x, int y, int l)
{// 剪枝if (abs(ex-x)+abs(ey-y) > t-l || l>t)return;// 边界if (x==ex && y==ey && l==t){cnt++;return;}for (int i = 0; i <= 3; i++) {int nx = x+dx[i];int ny = y+dy[i];if (nx>=0 && nx<=n && ny>=0 && ny<=m) // 未到边界{if (vis[nx][ny]==0 && a[nx][ny]=='.') // 未访问、是空地{vis[nx][ny] == 1;dfs(nx, ny, l+1);vis[nx][ny] == 0;}}}
}int main()
{// 输入cin >> n >> m >> t;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> a[i][j];}}cin >> sx >> sy >> ex >> ey;// dfsdfs(sx, sy, 0);// 输出cout << cnt;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/40116.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粗糙度轮廓仪功能简介:一体型轮廓仪功能亮点

在精密制造和质量控制领域&#xff0c;表面粗糙度和轮廓的精确测量是至关重要的。一体型轮廓仪为这一需求提供了全面的解决方案。它采用超高精度纳米衍射光学测量系统、超高直线度研磨级摩擦导轨、高性能直流伺服驱动系统、高性能计算机控制系统技术&#xff0c;为用户提供了一…

使用机器学习,通过文本分析,轻松实现原本复杂的情感分析

01、案例说明 本期分享案例是&#xff1a;文字分析-情感分析&#xff0c;内容是关于某部电影评论好坏的分析&#xff0c;使用大量的已知数据&#xff0c;通过监督学习的方法&#xff0c;可以对于未知的评论进行判断其为正面还是负面的评价。 对于数据分析&#xff0c;原来都是…

深⼊理解分布式锁常用方案,研究过Redisson和Curator框架的源码

分布式锁是分布式系统中确保多个节点对共享资源进行同步访问的关键技术。以下是对分布式锁常用方案以及Redisson和Curator框架源码的一些深入理解&#xff1a; ### 分布式锁常用方案 1. **基于数据库的乐观锁**&#xff1a; - 通过在数据表中添加版本号或时间戳字段&#…

Go语言学习:每日一练3

Go语言学习&#xff1a;每日一练3 目录 Go语言学习&#xff1a;每日一练3方法接口继承类型断言 方法 方法是一类有接收者参数的函数。 接收者的类型定义和方法的声明必须在一个包里 type MyInt intfunc (m MyInt) Add(add int) int {return int(m) add } //OR func (m *MyInt)…

巴图制自动化Profinet协议转Modbus协议模块连接PLC和电表通信

1、免编写Modbus轮询程序实现PLC与电表通信的方法 在智能化时代&#xff0c;工业自动控制中的PLC和电表之间的通信是一个常见的需求。传统上&#xff0c;为了使PLC与电表通信&#xff0c;通常需要编写Modbus查询程序来读取和控制数据。然而&#xff0c;使用 巴图制自动化Prof…

235、二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自…

用 AI 生成绘本,含大量 prompt

画图过程&#xff0c;为了保证绘本输出的风格统一&#xff0c;角色连贯&#xff0c;画面内容与故事保持一致 1、画风统一的解决办法&#xff1a;固定一个插画师的风格&#xff0c;可以输入插画师的名字&#xff0c;或者垫图&#xff0c;即上传你需要借鉴风格的图片 2、角色连贯…

Spring Security6.3.0版本出现无法解析符号

Spring Security 6.3.0版本出现“无法解析的符号”错误通常意味着项目中缺少了必要的类或者资源&#xff0c;或者可能是因为项目的依赖关系配置不正确。 解决方法&#xff1a; 确认依赖&#xff1a;检查pom.xml或build.gradle文件中是否正确添加了Spring Security的依赖&…

Redis中测试Stream的例子

当你想要测试 Redis 中的 Stream 功能时&#xff0c;可以通过 Redis 的命令行客户端或者使用任何支持 Redis 的编程语言来操作。下面我会给出一个简单的例子&#xff0c;使用 Redis 的命令行客户端 redis-cli 来测试 Stream 的基本功能。 准备工作 确保你已经安装并启动了 Re…

聚焦西安应博会|2024西安城市安全应急产业展9月精彩呈现

2024西安城市安全应急产业博览会 时间&#xff1a;2024年9月12日-14日 地点&#xff1a;西安国际会展中心 运营&#xff1a;西安西部文化产业博览会有限公司 【展会简介】 为推动安全应急装备向智能化、成套化、专业化方向发展&#xff0c;迎接新质生产力在应急产业新技术…

应广PMS150C系列 应广8位OTP IO单片机

1、特性 不建议使用于AC 阻容降压供电或有高EFT 要求的应用。应广不对使用于此类应用而不达安规要求负责 工作温度范围:-20C~70C 2、系统特性 1KW OTP 程序内存 64字节数据存储器 硬件 16位定时器 1个8位硬件PWM生成器 1个通用比较器 快速唤醒功能 …

nccl-test多机多卡测试

ssh免密登录 ubuntu默认安装有SSH client&#xff0c;还需要安装 SSH server sudo apt install openssh-server本机生成公私钥 cd ~/.ssh ssh-keygen -t rsa在.ssh/目录下&#xff0c;会生成两个文件&#xff1a;id_rsa和id_rsa.pub 注意&#xff1a;正确配置.ssh目录以及其…

linux下Java11无jre文件夹的问题

项目升级需要更高级的Java版本&#xff0c;于是下载了jdk-11.0.22_linux-x64_bin.tar.gz&#xff0c;解压后jdk-11.0.22下没有jre&#xff0c;导致eclipse下“build path”无法加载jre。 Java11以上版本不在提供jre&#xff0c;Java11安装后&#xff0c;需要如下处理&#xff1…

贝叶斯优化算法(Bayesian Optimization)及其Python 和 MATLAB 实现

贝叶斯优化算法&#xff08;Bayesian Optimization&#xff09;是一种基于贝叶斯统计理论的优化方法&#xff0c;通常用于在复杂搜索空间中寻找最优解。该算法能够有效地在未知黑盒函数上进行优化&#xff0c;并在相对较少的迭代次数内找到较优解&#xff0c;因此在许多领域如超…

ElementUI中的el-table解决宽度问题 - 根据内容自动撑开

在使用element-ui中&#xff0c;会发现表格组件el-table在未指定宽度情况下&#xff0c;会自动计算并给表格宽度赋值。但实际开发中&#xff0c;有时需要根据内容实际长度自动撑开显示&#xff0c;由内容的多少而决定表格的宽度&#xff0c;而不是默认宽度为100%。在默认情况下…

监控平台zabbix对接grafana

目录 1.安装grafana并启动 2.浏览器访问 3.导入zabbix数据&#xff0c;对接grafana 4.如何导入模板 5.使用zabbix监控nginx并发量连接数 5.1 修改nginx配置 5.2 编写监控数据脚本 5.3 设置键值 5.4 在zabbix web端完成自定义监控项 5.5 连接到grafana 以上一篇博客&l…

使用CubeIDE调试项目现stm32 no source available for “main() at 0x800337c:

使用CubeIDE调试项目现stm32 no source available for "main() at 0x800337c&#xff1a; 问题描述 使用CubeIDE编译工程代码和下载都没有任何问题&#xff0c;点击Debug调试工程时&#xff0c;出现stm32 no source available for "main() at 0x800337c 原因分析&a…

聊聊C++20的三向比较运算符 `<=>`

C20标准引入了许多新特性&#xff0c;其中之一是三向比较运算符 <>&#xff0c;也被称为太空船运算符。这个新运算符为C程序员提供了一种全新的比较对象的方式&#xff0c;它能有效简化比较逻辑&#xff0c;避免编写多个比较运算符重载的情况。 为什么需要三向比较运算符…

VirtualBox Ubuntu Sever配置双网卡

Ubuntu 版本&#xff1a;Ubuntu Server 2404 vitrualBox 网卡配置&#xff1a; 如上配置后&#xff0c;ifconfig 只能看到 网卡1 应用了。要应用 网卡2 需要更改文件 /etc/netplan/50-cloud-init.yaml&#xff08;不同的ubuntu版本这个文件名可能不同&#xff09; 首先 ifcon…

6.BeanFactory处理器Bean处理器

BeanFactoryPostProcessor BeanFactoryProcessor是Bean工厂处理器&#xff0c;对beanFactory的进行扩展&#xff0c;可以解析Configuration Bean注解。 主要功能是对BeanFactory的补充。 //获取所有bean工厂的处理器<Bean名字&#xff0c;bean工厂处理器>Map<Strin…