广搜逻辑
广搜代码核心思路
广搜伪代码
前面讲解的广度优先搜索案例都类似迷宫类的问题,但有些非迷宫类问题也可以使用广搜的思路解决
[【广搜2】填涂颜色]
【算法分析】 可以在外面增加一圈 0,然后从 (0,0) 位置开始广搜所有为 0 的位置,没有被搜索到且为 0 的位置就应该变为 2。 【参考代码】 #include<bits/stdc++.h> using namespace std; int a[39][39]; bool vis[39][39]; struct node { int x, y; }l,r; int n; int dir[4][2] = { -1,0,0,1,1,0,0,-1 }; void bfs(int x, int y) { queue<node> q; q.push({ x,y }); vis[x][y] = 1; while (q.size()) { r = q.front(); q.pop(); for (int i = 0; i < 4; i++) { l.x = r.x + dir[i][0], l.y = r.y + dir[i][1]; if (l.x >= 0 && l.x <= n + 1 && l.y >= 0 && l.y <= n + 1 && !vis[l.x][l.y] && a[l.x][l.y] == 0) { vis[l.x][l.y] = 1; q.push(l); } } } } int main() { cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> a[i][j]; } } bfs(0, 0); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (a[i][j] == 0 && !vis[i][j]) { cout << 2 << " "; } else cout << a[i][j] << " "; } cout << '\n'; } return 0; }View Code
[【广搜2】抓住那头牛]
【算法分析】 由于位置的个数很少且要求最小步数,可以考虑从 n 位置开始广搜,同时用一个数组 d,d i 表示从 n 位置到 i 位置需要的步数,最后输出 d k 即可。 【参考代码】 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 9; int d[maxn]; int main() { int n, k; cin >> n >> k; memset(d, -1, sizeof(d)); d[n] = 0; queue<int> q; q.push(n); while (q.size()) { int r = q.front(); q.pop(); if (r >= 1 && d[r - 1] == -1) { d[r - 1] = d[r] + 1; q.push(r - 1); } if (r < 1e5 && d[r + 1] == -1) { d[r + 1] = d[r] + 1; q.push(r + 1); } if (2 * r <= 1e5 && d[2 * r] == -1) { d[2 * r] = d[r] + 1; q.push(2 * r); } } cout << d[k]; return 0; }View Code
[【广搜2】奇怪的电梯]
【算法分析】 由于位置的个数很少且要求最小步数,可以考虑从 A 位置开始广搜,同时用一个数组 d,di 表示从 A 位置到 i 位置需要的步数,最后输出 d B 即可。 【参考代码】 #include<bits/stdc++.h> using namespace std; const int maxn = 2e2 + 9; int d[maxn], k[maxn]; int main() { int N, A, B; cin >> N >> A >> B; for (int i = 1; i <= N; i++) cin >> k[i]; memset(d, -1, sizeof(d)); d[A] = 0; queue<int> q; q.push(A); while (q.size()) { int r = q.front(); q.pop(); if (r + k[r] <= N && d[r + k[r]] == -1) { d[r + k[r]] = d[r] + 1; q.push(r + k[r]); } if (r - k[r] >= 1 && d[r - k[r]] == -1) { d[r - k[r]] = d[r] + 1; q.push(r - k[r]); } } cout << d[B]; return 0; }View Code
[【广搜2】倒水问题]
【算法分析】 可以从 (0,0) 状态开始广搜,在广搜的每一步记录 x,y,step,s,分别表示第一个杯子装的水,第二个杯子装的水,达到这个状态需要的步数,达到这个状态的操作步骤。 【参考代码】 #include<bits/stdc++.h> using namespace std; const int maxn = 1e2 + 9; bool vis[maxn][maxn]; struct node { int x, y, step; string s; }l, r; int main() { int n, m, k; cin >> n >> m >> k; vis[0][0] = 1; queue<node> q; q.push({ 0,0,0,"" }); while (q.size()) { r = q.front(); q.pop(); if (r.x == k || r.y == k) { cout << r.step << '\n' << r.s; return 0; } l.x = n, l.y = r.y, l.step = r.step + 1, l.s = r.s + "FILL(1)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } l.x = r.x, l.y = m, l.step = r.step + 1, l.s = r.s + "FILL(2)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } l.x = 0, l.y = r.y, l.step = r.step + 1, l.s = r.s + "DROP(1)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } l.x = r.x, l.y = 0, l.step = r.step + 1, l.s = r.s + "DROP(2)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } l.x = max(0, r.x + r.y - m), l.y = min(m, r.x + r.y), l.step = r.step + 1, l.s = r.s + "POUR(1,2)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } l.x = min(n, r.x + r.y), l.y = max(0, r.x + r.y - n), l.step = r.step + 1, l.s = r.s + "POUR(2,1)\n"; if (!vis[l.x][l.y]) { vis[l.x][l.y] = 1; q.push(l); } } cout << "impossible"; return 0; }View Code
标签:05,U5,位置,C++,int,maxn,&&,push,步数 From: https://www.cnblogs.com/jayxuan/p/17831294.html