链接索引🔗:
第八章 广度优先搜索算
全部都是用队列(queue)来做,超方便!!!
1329:【例8.2】细胞
#include <bits/stdc++.h>
using namespace std;
struct Node{
int x, y;
};
void bfs(int s1, int s2, int n, int m, vector<vector<int>>& a, vector<vector<bool>>& v){
static const int fx[4] = {-1, 1, 0, 0};
static const int fy[4] = {0, 0, -1, 1};
queue<Node> q;
q.push({s1, s2});
v[s1][s2] = true;
while (!q.empty()){
Node c = q.front();
q.pop();
for (int i = 0; i < 4; i++){
int tx = c.x + fx[i];
int ty = c.y + fy[i];
if (tx >= 0 && tx < n && ty >= 0 && ty < m && a[tx][ty] != 0 && !v[tx][ty]){
v[tx][ty] = true;
q.push({tx, ty});
}
}
}
}
int cnt(int n, int m, vector<vector<int>>& a){
vector<vector<bool>> v;
v.resize(n, vector<bool>(m, false));
int sum = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (a[i][j] != 0 && !v[i][j]){
bfs(i, j, n, m, a, v);
sum++;
}
}
}
return sum;
}
int main(){
int n, m;
cin >> n >> m;
vector<vector<int>> a;
a.resize(n, vector<int> (m));
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
char c;
cin >> c;
a[i][j] = c - '0';
}
}
cout << cnt(n, m, a) << endl;
return 0;
}
1330:【例8.3】最少步数
#include <bits/stdc++.h>
using namespace std;
struct Node {
int x, y, dist;
};
int bfs(int s, int e) {
static const int fx[12] = {-1, -2, -2, -1, 1, 2, 2, 1, -2, -2, 2, 2};
static const int fy[12] = {-2, -1, 1, 2, 2, 1, -1, -2, 2, -2, -2, 2};
vector<vector<bool>> v;
v.resize(110, vector<bool>(110, false));
queue<Node> q;
q.push({s, e, 0});
v[s][e] = true;
while (!q.empty()) {
Node cur = q.front();
q.pop();
if (cur.x == 1 && cur.y == 1) {
return cur.dist;
}
for (int i = 0; i < 12; i++) {
int tx = cur.x + fx[i];
int ty = cur.y + fy[i];
if (tx >= 1 && tx <= 100 && ty >= 1 && ty <= 100 && !v[tx][ty]) {
v[tx][ty] = true;
q.push({tx, ty, cur.dist + 1});
}
}
}
return -1;
}
int main() {
int ax, ay, bx, by;
cin >> ax >> ay >> bx >> by;
cout << bfs(ax, ay) << endl;
cout << bfs(bx, by) << endl;
return 0;
}
1248:Dungeon Master
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Node {
int x, y, z, s;
};
int bfs(const vector<vector<string>>& a, int l, int r, int c) {
static const int fx[6] = {-1, 1, 0, 0, 0, 0};
static const int fy[6] = {0, 0, -1, 1, 0, 0};
static const int fz[6] = {0, 0, 0, 0, -1, 1};
vector<vector<vector<bool>>> vis(l, vector<vector<bool>>(r, vector<bool>(c, false)));
queue<Node> q;
for (int i = 0; i < l; i++) {
for (int j = 0; j < r; j++) {
for (int k = 0; k < c; k++) {
if (a[i][j][k] == 'S') {
q.push({i, j, k, 0});
vis[i][j][k] = true;
break;
}
}
}
}
while (!q.empty()) {
Node current = q.front();
q.pop();
if (a[current.x][current.y][current.z] == 'E') {
return current.s;
}
for (int i = 0; i < 6; ++i) {
int tx = current.x + fx[i];
int ty = current.y + fy[i];
int tz = current.z + fz[i];
if (tx >= 0 && tx < l && ty >= 0 && ty < r && tz >= 0 && tz < c && !vis[tx][ty][tz] && a[tx][ty][tz] != '#') {
vis[tx][ty][tz] = true;
q.push({tx, ty, tz, current.s + 1});
}
}
}
return -1;
}
int main() {
int l, r, c;
while (cin >> l >> r >> c && (l || r || c)) {
vector<vector<string>> a;
a.resize(l, vector<string>(r));
for (int i = 0; i < l; ++i) {
for (int j = 0; j < r; ++j) {
cin >> a[i][j];
}
}
int result = bfs(a, l, r, c);
if (result != -1) {
cout << "Escaped in " << result << " minute(s)." << endl;
} else {
cout << "Trapped!" << endl;
}
}
return 0;
}
1249:Lake Counting
记住这里的方向数组要定义 8 个哟!因为是数池塘(八方向)——不折不扣的宽度优先搜索的经典问题
#include <bits/stdc++.h>
using namespace std;
int n, m;
struct Node {
int x, y;
};
int fx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int fy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
void bfs(vector<vector<char>>& l, int x, int y) {
queue<Node> q;
q.push({x, y});
l[x][y] = '.';
while (!q.empty()) {
Node cur = q.front();
q.pop();
for (int i = 0; i < 8; i++) {
int tx = cur.x + fx[i], ty = cur.y + fy[i];
if (tx >= 0 && tx < n && ty >= 0 && ty < m && l[tx][ty] == 'W') {
l[tx][ty] = '.';
q.push({tx, ty});
}
}
}
}
int main() {
cin >> n >> m;
vector<vector<char>> l(n, vector<char>(m));
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
cin >> l[i][j];
}
}
int p = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (l[i][j] == 'W') {
bfs(l, i, j);
p++;
}
}
}
cout << p << endl;
return 0;
}
1250:The Castle
这一道题我认为是比较复杂的
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
vector<vector<int>> c(50, vector<int>(50));
vector<vector<bool>> v(50, vector<bool>(50, false));
int m, n;
int fx[4] = {-1, 0, 1, 0};
int fy[4] = {0, 1, 0, -1};
int w[4] = {2, 4, 8, 1};
int bfs(int x, int y) {
queue<pair<int, int>> q;
q.push({x, y});
v[x][y] = true;
int a = 0;
while (!q.empty()) {
int x1 = q.front().first;
int y1 = q.front().second;
q.pop();
a++;
for (int i = 0; i < 4; i++) {
int tx = x1 + fx[i];
int ty = y1 + fy[i];
if (tx >= 0 && tx < m && ty >= 0 && ty < n && !v[tx][ty] && (c[x1][y1] & w[i]) == 0) {
v[tx][ty] = true;
q.push({tx, ty});
}
}
}
return a;
}
int main() {
cin >> m >> n;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> c[i][j];
}
}
int r = 0, ma = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!v[i][j]) {
r++;
ma = max(ma, bfs(i, j));
}
}
}
cout << r << endl << ma << endl;
return 0;
}
1251:仙岛求药
#include <bits/stdc++.h>
using namespace std;
char a[25][25];
int m, n;
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
struct Node{
int x, y, step;
};
int bfs(int s1, int s2, int e1, int e2)
{
queue<Node> q;
q.push({s1, s2, 0});
a[s1][s2] = '#';
while (!q.empty())
{
Node current = q.front();
q.pop();
if (current.x == e1 && current.y == e2)
{
return current.step;
}
for (int i = 0; i < 4; i++)
{
int tx = current.x + fx[i];
int ty = current.y + fy[i];
if (a[tx][ty] == '.' || a[tx][ty] == '*')
{
a[tx][ty] = '#';
q.push({tx, ty, current.step + 1});
}
}
}
return -1;
}
int main()
{
while (cin >> m >> n)
{
int s1, s2, e1, e2;
memset(a, 0, sizeof(a));
if (m == 0 && n == 0)
{
break;
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
if (a[i][j] == '@')
{
s1 = i;
s2 = j;
}
if (a[i][j] == '*')
{
e1 = i;
e2 = j;
}
}
}
cout << bfs(s1, s2, e1, e2) << endl;
}
return 0;
}
1252:走迷宫
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Node {
int x, y, step;
};
// 方向数组,表示上、下、左、右四个方向的移动
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int bfs(const vector<vector<char>>& maze, int R, int C) {
vector<vector<bool>> visited(R, vector<bool>(C, false)); // 访问状态数组
queue<Node> q;
q.push({0, 0, 1}); // 从左上角开始,步数为1(包括起点)
visited[0][0] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
// 到达右下角
if (current.x == R - 1 && current.y == C - 1) {
return current.step;
}
// 尝试四个方向的移动
for (int i = 0; i < 4; ++i) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 0 && nx < R && ny >= 0 && ny < C && !visited[nx][ny] && maze[nx][ny] == '.') {
visited[nx][ny] = true;
q.push({nx, ny, current.step + 1});
}
}
}
return -1; // 如果无法到达终点(虽然题目保证可以到达)
}
int main() {
int R, C;
cin >> R >> C;
vector<vector<char>> maze(R, vector<char>(C));
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
cin >> maze[i][j];
}
}
cout << bfs(maze, R, C) << endl;
return 0;
}
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Node {
int x, y, step;
};
int fx[4] = {-1, 1, 0, 0};
int fy[4] = {0, 0, -1, 1};
int bfs(const vector<vector<char>>& a, int r, int c) {
vector<vector<bool>> v(r, vector<bool>(c, false));
queue<Node> q;
q.push({0, 0, 1});
v[0][0] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.x == r - 1 && current.y == c - 1) {
return current.step;
}
for (int i = 0; i < 4; i++) {
int tx = current.x + fx[i];
int ty = current.y + fy[i];
if (tx >= 0 && tx < r && ty >= 0 && ty < c && !v[tx][ty] && a[tx][ty] == '.') {
v[tx][ty] = true;
q.push({tx, ty, current.step + 1});
}
}
}
return -1;
}
int main() {
int r, c;
cin >> r >> c;
vector<vector<char>> a;
a.resize(r, vector<char>(c));
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cin >> a[i][j];
}
}
cout << bfs(a, r, c) << endl;
return 0;
}
1253:抓住那头牛
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAX = 100001; // 数轴的最大范围
int bfs(int N, int K) {
vector<int> visited(MAX, 0); // 访问数组,同时记录到达每个位置的最短时间
queue<int> q;
q.push(N); // 将起始位置入队
visited[N] = 1; // 标记起始位置已访问,初始化为1而不是0,用于避免特殊情况N=0
while (!q.empty()) {
int current = q.front();
q.pop();
// 如果当前位置就是牛的位置,返回当前已经花费的时间
if (current == K) {
return visited[current] - 1; // 返回结果时减去初始的1
}
// 尝试三种移动方式
int nextPos = current - 1;
if (nextPos >= 0 && !visited[nextPos]) {
visited[nextPos] = visited[current] + 1;
q.push(nextPos);
}
nextPos = current + 1;
if (nextPos < MAX && !visited[nextPos]) {
visited[nextPos] = visited[current] + 1;
q.push(nextPos);
}
nextPos = current * 2;
if (nextPos < MAX && !visited[nextPos]) {
visited[nextPos] = visited[current] + 1;
q.push(nextPos);
}
}
return -1; // 如果没有找到路径,返回-1(理论上不会发生,因为题目保证了解的存在)
}
int main() {
int N, K;
cin >> N >> K;
cout << bfs(N, K) << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 1e5 + 100;
vector<bool> vis(MAX_SIZE);
struct Node{
int x, step;
};
int bfs(int n, int k)
{
queue<Node> q;
q.push({n, 0});
vis[n] = true;
while (!q.empty())
{
Node current = q.front();
q.pop();
if (current.x == k)
{
return current.step;
}
for (int i = 0; i < 3; ++i)
{
int tx;
if (i == 0) tx = current.x - 1;
if (i == 1) tx = current.x + 1;
if (i == 2) tx = current.x * 2;
if (tx >= 0 && tx < 100000 && vis[tx] == false)
{
vis[tx] = true;
q.push({tx, current.step + 1});
}
}
}
return -1;
}
int main()
{
int n, k;
cin >> n >> k;
if (n == k)
{
cout << 0 << endl;
}
else
{
cout << bfs(n, k) << endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int q[100001][3], a[100001], head = 0, tail = 1, n, k, t, xx;
int main()
{
cin >> n >> k;
if (n == k)
{
cout << 0 << endl;
return 0;
}
q[1][0] = n;
q[1][1] = 0;
a[n] = 1;
while (head <= tail)
{
head++;
xx = q[head][0];
for (int i = 1; i <= 3; i++)
{
if (i == 1) t = xx + 1;
if (i == 2) t = xx - 1;
if (i == 3) t = 2 * xx;
if (t >= 0 && t <= 100000 && a[t] == 0)
{
tail++;
q[tail][0] = t;
q[tail][1] = q[head][1] + 1;
a[t] = 1;
if (t == k)
{
cout << q[tail][1] << endl;
return 0;
}
}
}
}
return 0;
}
1254:走出迷宫
第八章中最简单的一道题!!!
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 100;
vector<vector<char>> maze;
vector<vector<bool>> visited;
int dx[4] = {0, 0, -1, 1}; // 上下左右移动
int dy[4] = {-1, 1, 0, 0};
int n, m; // 迷宫的行数和列数
struct Node {
int x, y, step;
};
int bfs(int sx, int sy, int ex, int ey) {
queue<Node> q;
q.push({sx, sy, 0});
visited[sx][sy] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.x == ex && current.y == ey) {
return current.step;
}
for (int i = 0; i < 4; ++i) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && maze[nx][ny] != '#') {
visited[nx][ny] = true;
q.push({nx, ny, current.step + 1});
}
}
}
return -1; // 如果没有路径可以到达
}
int main() {
cin >> n >> m;
maze.resize(n, vector<char>(m)); // 使用resize为迷宫分配空间
visited.resize(n, vector<bool>(m, false)); // 同样为访问状态分配空间
int sx, sy, ex, ey; // 起点和终点坐标
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> maze[i][j];
if (maze[i][j] == 'S') {
sx = i;
sy = j;
}
if (maze[i][j] == 'T') {
ex = i;
ey = j;
}
}
}
cout << bfs(sx, sy, ex, ey) << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n, m;
char a[200][200];
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
struct Node{
int x, y, dist;
};
int bfs(int s1, int s2, int e1, int e2)
{
queue<Node> q;
q.push({s1, s2, 0});
while (!q.empty())
{
Node current = q.front();
q.pop();
if (current.x == e1 && current.y == e2)
{
return current.dist;
}
for (int i = 0; i < 4; i++)
{
int tx = current.x + fx[i];
int ty = current.y + fy[i];
if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && (a[tx][ty] == '.' || a[tx][ty] == 'T'))
{
a[tx][ty] = '#';
q.push({tx, ty, current.dist + 1});
}
}
}
}
int main()
{
int 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];
if (a[i][j] == 'S')
{
s1 = i;
s2 = j;
}
if (a[i][j] == 'T')
{
e1 = i;
e2 = j;
}
}
}
cout << bfs(s1, s2, e1, e2) << endl;
return 0;
}
1255:迷宫问题
#include<iostream>
#include<queue>
using namespace std;
const int N = 5;
struct Node {
int x, y;
};
queue<Node> q;
Node pre[N][N];
int g[N][N], dir[4][2] = { -1,0,0,1,1,0,0,-1 };
bool st[N][N];
// 将(x,y)入队并标记,记录(x,y)的前驱是(tx,ty)
void push(int x, int y, int tx, int ty) {
Node node = { x,y };
q.push(node);
st[x][y] = true;
pre[x][y].x = tx;
pre[x][y].y = ty;
}
void print(int x, int y) {
if (x == -1 && y == -1) return;
print(pre[x][y].x, pre[x][y].y);
cout << "(" << x << ", " << y << ")" << endl;
}
void bfs() {
push(0, 0, -1, -1);
while (q.size()) {
Node t = q.front();
q.pop();
if (t.x == 4 && t.y == 4) {
print(4, 4);
break;
}
for (int i = 0; i < 4; i++) {
int nx = t.x + dir[i][0], ny = t.y + dir[i][1];
if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && g[nx][ny] == 0 && !st[nx][ny]) push(nx, ny, t.x, t.y);
}
}
}
int main() {
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) cin >> g[i][j];
bfs();
return 0;
}
这段代码是参考哪一位博主的我忘记了,如果知道的话,就留言
1256:献给阿尔吉侬的花束
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Node {
int x, y, dist;
};
vector<vector<char>> a;
int fx[4] = {1, -1, 0, 0};
int fy[4] = {0, 0, 1, -1};
int bfs(int s1, int s2, int e1, int e2);
int main() {
int t;
cin >> t;
for (int k = 0; k < t; k++) {
int r, c;
cin >> r >> c;
a.clear();
a.resize(r, vector<char>(c));
int s1, s2, e1, e2;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cin >> a[i][j];
if (a[i][j] == 'S') {
s1 = i;
s2 = j;
}
if (a[i][j] == 'E') {
e1 = i;
e2 = j;
}
}
}
int ans = bfs(s1, s2, e1, e2);
if (ans == -1) {
cout << "oop!" << endl;
} else {
cout << ans << endl;
}
}
return 0;
}
int bfs(int s1, int s2, int e1, int e2) {
queue<Node> q;
q.push({s1, s2, 0});
a[s1][s2] = '#';
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.x == e1 && current.y == e2) {
return current.dist;
}
int tx, ty;
for (int i = 0; i < 4; i++) {
tx = current.x + fx[i];
ty = current.y + fy[i];
if (tx >= 0 && tx < a.size() && ty >= 0 && ty < a[0].size() && (a[tx][ty] == '.' || a[tx][ty] == 'E')) {
a[tx][ty] = '#';
q.push({tx, ty, current.dist + 1});
}
}
}
return -1;
}
1257:Knight Moves
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct Position {
int x, y, step;
};
// 马的8种可能移动
int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
int bfs(int L, int sx, int sy, int ex, int ey) {
vector<vector<bool>> visited(L, vector<bool>(L, false));
queue<Position> q;
q.push({sx, sy, 0});
visited[sx][sy] = true;
while (!q.empty()) {
Position current = q.front();
q.pop();
if (current.x == ex && current.y == ey) {
return current.step;
}
for (int i = 0; i < 8; ++i) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 0 && nx < L && ny >= 0 && ny < L && !visited[nx][ny]) {
visited[nx][ny] = true;
q.push({nx, ny, current.step + 1});
}
}
}
return -1; // 这种情况理论上不会发生,因为题目保证了解的存在
}
int main() {
int t;
cin >> t;
while (t--) {
int L, sx, sy, ex, ey;
cin >> L >> sx >> sy >> ex >> ey;
cout << bfs(L, sx, sy, ex, ey) << endl;
}
return 0;
}
完结撒花!!!!!
| 🌸 |
🌸 | 🌸 |
| 🌸 | | 🌸 |
🌸 | 🌸 |
| 🌸 |
| 🌸 |
🌸 | 🌸 |
| 🌸 | | 🌸 |
🌸 | 🌸 |
| 🌸 |