1.广搜基础-用广搜实现深搜
2.广搜求最少步数和最短路径
1432. 走出迷宫的最少步数
基础版本
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 41; // 增加大小以从1开始索引
char maze[MAXN][MAXN];
int visited[MAXN][MAXN];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int R, C;
int bfs() {
queue<pair<int, int>> q;
q.push({1, 1}); // 从(1, 1)开始
visited[1][1] = 1;
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
if (x == R && y == C) {
return visited[x][y];
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 1 && nx <= R && ny >= 1 && ny <= C && maze[nx][ny] == '.' && visited[nx][ny] == 0) {
q.push({nx, ny});
visited[nx][ny] = visited[x][y] + 1;
}
}
}
return -1;
}
int main() {
cin >> R >> C;
for (int i = 1; i <= R; i++)
for (int j = 1; j <= C; j++) {
cin >> maze[i][j];
visited[i][j] = 0;
}
cout << bfs()<< endl; // 减去起始位置的步数
return 0;
}
STL库版本
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 41;
int n, m;
vector<vector<char>> maze;
vector<vector<bool>> visited;
// 定义结构体
struct Node {
int x, y, step;
};
int dx[4] = {0, 0, 1, -1}; // 方向数组,表示上下左右
int dy[4] = {1, -1, 0, 0};
int bfs() {
queue<Node> q;
q.push({1, 1, 1}); // 初始化起点和步数
visited[1][1] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.x == n && current.y == m) {
return current.step;
}
for (int i = 0; i < 4; i++) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && maze[nx][ny] == '.' && !visited[nx][ny]) {
visited[nx][ny] = true;
q.push({nx, ny, current.step + 1});
}
}
}
return -1;
}
int main() {
cin >> n >> m;
maze.resize(n + 1, vector<char>(m + 1));
visited.resize(n + 1, vector<bool>(m + 1, false));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> maze[i][j];
cout << bfs() << endl;
return 0;
}
1433. 走出迷宫的最少步数2
基础版本
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 101;
char maze[MAXN][MAXN];
int visited[MAXN][MAXN];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int n, m;
int bfs(int startX, int startY) {
queue<pair<int, int>> q;
q.push({startX, startY});
visited[startX][startY] = 1;
while (!q.empty()) {
auto [x, y] = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] != '#' && visited[nx][ny] == 0) {
visited[nx][ny] = visited[x][y] + 1;
if (maze[nx][ny] == 'T') {
return visited[nx][ny] - 1;
}
q.push({nx, ny});
}
}
}
return -1; // 如果没有找到路径
}
int main() {
cin >> n >> m;
pair<int, int> start;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> maze[i][j];
if (maze[i][j] == 'S') {
start = {i, j};
}
visited[i][j] = 0;
}
}
cout << bfs(start.first, start.second) << endl;
return 0;
}
STL库版本
#include <bits/stdc++.h>
using namespace std;
vector<vector<char>> path;
vector<vector<bool>> vis;
int n,m;
struct Node{
int x,y,step;
};
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};
int bfs(int startX,int startY,int endX,int endY)
{
queue<Node> q;
vis[startX][startY] = true;
q.push({startX,startY,0});
while(!q.empty())
{
Node current = q.front();
q.pop();
if(current.x == endX && current.y == endY)
{
return current.step;
}
for(int i=0; i<4; i++)
{
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&(path[nx][ny]=='.'||path[nx][ny]=='T')&&!vis[nx][ny])
{
vis[nx][ny] = true;
q.push({nx,ny,current.step+1});
}
}
}
return -1;
}
int main()
{
cin>>n>>m;
path.resize(n+1,vector<char>(m+1));
vis.resize(n+1,vector<bool>(m+1,false));
int startX,startY,endX,endY;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>path[i][j];
if(path[i][j]=='S')
{
startX = i;
startY = j;
}
if(path[i][j]=='T')
{
endX = i;
endY = j;
}
}
}
cout<<bfs(startX,startY,endX,endY)<<endl;
return 0;
}
1900. 采药的最短路径
基础版本
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXM = 21;
const int MAXN = 21;
vector<vector<char>> maze;
vector<vector<int>> visited;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int M, N;
int bfs(int startX, int startY) {
queue<pair<int, int>> q;
q.push({startX, startY});
visited[startX][startY] = 1;
while (!q.empty()) {
auto [x, y] = q.front();
q.pop();
if (maze[x][y] == '*') {
return visited[x][y];
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 1 && nx <= M && ny >= 1 && ny <= N && maze[nx][ny] != '#' && visited[nx][ny] == 0) {
visited[nx][ny] = visited[x][y] + 1;
q.push({nx, ny});
}
}
}
return -1;
}
int main() {
cin >> M >> N;
maze.resize(M + 1, vector<char>(N + 1));
visited.resize(M + 1, vector<int>(N + 1, 0));
pair<int, int> start;
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
cin >> maze[i][j];
if (maze[i][j] == '@') {
start = {i, j};
}
}
}
int result = bfs(start.first, start.second);
cout << (result == -1 ? result : result - 1) << endl; // 减去起始点
return 0;
}
STL库版本
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int n,m;
struct Node{
int x,y,step;
};
vector<vector<char>> maze;
vector<vector<int>> vis;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int bfs(int startX,int startY,int endX,int endY)
{
queue<Node> q;
vis[startX][startY] = true;
q.push({startX,startY,0});
while(!q.empty())
{
Node current = q.front();
q.pop();
if(current.x == endX && current.y == endY)
{
return current.step;
}
for(int i=0; i<4; i++)
{
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&(maze[nx][ny]=='.'||maze[nx][ny]=='*')&&!vis[nx][ny])
{
vis[nx][ny] = true;
q.push({nx,ny,current.step+1});
}
}
}
return -1;
}
int main() {
cin >> n >> m;
maze.resize(n+1, vector<char>(m+1));
vis.resize(n+1, vector<int>(m+1, 0));
int startX,startY,endX,endY;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>maze[i][j];
if(maze[i][j]=='@')
{
startX = i;
startY = j;
}
if(maze[i][j]=='*')
{
endX = i;
endY = j;
}
}
}
cout<<bfs(startX,startY,endX,endY)<<endl;
return 0;
}
2109. 古希腊之争
#include<bits/stdc++.h>
using namespace std;
vector<vector<char>> maze;
vector<vector<bool>> visited;
int n,m,c;
int startX,startY,lastX,lastY;
struct Node{
int x,y,step;
};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int bfs(int startX,int startY,int lastX,int lastY){
queue<Node> q;
q.push({startX,startY,0});
visited[startX][startY]=true;
while(!q.empty()){
Node current=q.front();
q.pop();
if(current.x==lastX&¤t.y==lastY){
return current.step;
}
for(int i=0;i<4;i++){
int mx=current.x+dx[i];
int my=current.y+dy[i];
if(mx>=1&&mx<=n&&my>=1&&my<=m&&(maze[mx][my]=='.'||maze[mx][my]=='E')&&!visited[mx][my])
{
visited[mx][my]=true;
q.push({mx,my,current.step+1});
}
}
}
return -1;
}
int main(){
cin>>n>>m>>c;
maze.resize(n+1,vector<char>(m+1));
visited.resize(n+1,vector<bool>(m+1,false));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>maze[i][j];
if(maze[i][j]=='S'){
startX=i;
startY=j;
}
if(maze[i][j]=='E'){
lastX=i;
lastY=j;
}
}
}
int ans=bfs(startX,startY,lastX,lastY);
cout<<(ans==-1?-1:ans*c)<<endl;
return 0;
}
1442. 走出迷宫的最短路径
基础版本1.0
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 160;
int maze[MAXN][MAXN];
int prevX[MAXN][MAXN], prevY[MAXN][MAXN];
bool visited[MAXN + 1][MAXN + 1];
int dx[4] = {-1, 1, 0, 0}; // 四个方向的x坐标变化(上下左右)
int dy[4] = {0, 0, -1, 1}; // 四个方向的y坐标变化(上下左右)
int n, m;
void printPath(int endX, int endY) {
if (prevX[endX][endY] == 0 && prevY[endX][endY] == 0) {
cout << "(" << endX << "," << endY << ")";
return;
}
printPath(prevX[endX][endY], prevY[endX][endY]);
cout << "->(" << endX << "," << endY << ")";
}
void bfs(int startX, int startY, int endX, int endY) {
queue<pair<int, int>> q;
q.push({startX, startY});
visited[startX][startY] = true;
prevX[startX][startY] = 0;
prevY[startX][startY] = 0;
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
if (x == endX && y == endY) {
printPath(endX, endY);
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 <= m && maze[tx][ty] == 0 && !visited[tx][ty]) {
q.push({tx, ty});
visited[tx][ty] = true;
prevX[tx][ty] = x;
prevY[tx][ty] = y;
}
}
}
cout << "no way";
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> maze[i][j];
int startX, startY, endX, endY;
cin >> startX >> startY >> endX >> endY;
bfs(startX, startY, endX, endY);
return 0;
}
STL局部变量版本2.0
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 50;
int n, m;
vector<vector<int>> maze;
vector<vector<bool>> visited;
vector<vector<pair<int, int>>> prevStep; // 只修改这个数组的名称
int dx[4] = {0, 0, 1, -1}; // 方向数组,表示上下左右
int dy[4] = {1, -1, 0, 0};
void printPath(int x, int y) {
if (prevStep[x][y] == make_pair(0, 0)) { // 使用新名称 prevStep
cout << "(" << x << "," << y << ")";
return;
}
printPath(prevStep[x][y].first, prevStep[x][y].second); // 使用新名称 prevStep
cout << "->(" << x << "," << y << ")";
}
bool bfs(int startX, int startY, int endX, int endY) {
queue<pair<int, int>> q;
q.push({startX, startY});
visited[startX][startY] = true;
while (!q.empty()) {
pair<int, int> front = q.front();
q.pop();
int x = front.first, y = front.second;
if (x == endX && y == endY) {
printPath(endX, endY);
return true;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && maze[nx][ny] == 0 && !visited[nx][ny]) {
q.push({nx, ny});
visited[nx][ny] = true;
prevStep[nx][ny] = {x, y}; // 使用新名称 prevStep
}
}
}
return false;
}
int main() {
cin >> n >> m;
maze.resize(n + 1, vector<int>(m + 1));
visited.resize(n + 1, vector<bool>(m + 1, false));
prevStep.resize(n + 1, vector<pair<int, int>>(m + 1, {0, 0})); // 使用新名称 prevStep
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> maze[i][j];
}
}
int startX, startY, endX, endY;
cin >> startX >> startY >> endX >> endY;
if (!bfs(startX, startY, endX, endY)) {
cout << "no way";
}
return 0;
}
全局变量版本3.0
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int n, m;
vector<vector<int>> maze;
vector<vector<bool>> visited;
vector<vector<pair<int, int>>> prevStep;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
void printPath(int x, int y) {
if (prevStep[x][y] == make_pair(0, 0)) {
cout << "(" << x << "," << y << ")";
return;
}
printPath(prevStep[x][y].first, prevStep[x][y].second);
cout << "->(" << x << "," << y << ")";
}
bool bfs(int startX, int startY, int endX, int endY) {
queue<pair<int, int>> q;
q.push({startX, startY});
visited[startX][startY] = true;
while (!q.empty()) {
pair<int, int> front = q.front();
q.pop();
int x = front.first, y = front.second;
if (x == endX && y == endY) {
printPath(endX, endY);
return true;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && maze[nx][ny] == 0 && !visited[nx][ny]) {
q.push({nx, ny});
visited[nx][ny] = true;
prevStep[nx][ny] = {x, y};
}
}
}
return false;
}
int main() {
cin >> n >> m;
maze.resize(n + 1, vector<int>(m + 1));
visited.resize(n + 1, vector<bool>(m + 1, false));
prevStep.resize(n + 1, vector<pair<int, int>>(m + 1, {0, 0}));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> maze[i][j];
int startX, startY, endX, endY;
cin >> startX >> startY >> endX >> endY;
if (!bfs(startX, startY, endX, endY)) {
cout << "no way";
}
return 0;
}
1819. 奇怪的电梯
这个问题实质上是一个图的最短路径问题。我们可以将每个楼层视为图中的一个节点,若能从一个楼层直接到达另一个楼层,则在这两个节点之间建立一条边。问题转化为在这个图中找出从起始楼层(节点 A)到目标楼层(节点 B)的最短路径。
对于数组和vector
的两种实现方式,我们可以采用类似的逻辑,只是在存储楼层之间的关系时,使用不同的数据结构。以下是两种方法的详细解析和代码实现:
使用数组的方法
- 初始化: 创建一个数组,用于存储每个楼层可以直接到达的楼层。
- 建图: 遍历每个楼层,根据题目规则添加边。
- 寻找最短路径: 使用广度优先搜索(BFS)找到从 A 到 B 的最短路径。
C++代码实现(使用数组)
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 205;
int n, A, B;
int k[MAXN];
int step[MAXN]; // 用于记录到达每个楼层的最少步数
void bfs() {
queue<int> q;
q.push(A);
step[A] = 0;
while (!q.empty()) {
int current = q.front();
q.pop();
if (current == B) return; // 到达目标楼层
// 探索下一步
int next_up = current + k[current];
int next_down = current - k[current];
if (next_up <= n && step[next_up] == -1) { // 向上
step[next_up] = step[current] + 1;
q.push(next_up);
}
if (next_down >= 1 && step[next_down] == -1) { // 向下
step[next_down] = step[current] + 1;
q.push(next_down);
}
}
}
int main() {
cin >> n >> A >> B;
for (int i = 1; i <= n; i++) {
cin >> k[i];
step[i] = -1;
}
bfs();
cout << (step[B] != -1 ? step[B] : -1) << endl;
return 0;
}
使用vector的方法
对于使用vector
的方法,逻辑和数组方法相似,只不过是将数组换成vector
来存储数据。
C++代码实现(使用vector)
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int n, A, B;
vector<int> k;
vector<int> step; // 使用 vector 来存储步数
void bfs() {
queue<int> q;
q.push(A);
step[A] = 0;
while (!q.empty()) {
int current = q.front();
q.pop();
if (current == B) return;
int next_up = current + k[current];
int next_down = current - k[current];
if (next_up <= n && step[next_up] == -1) {
step[next_up] = step[current] + 1;
q.push(next_up);
}
if (next_down >= 1 && step[next_down] == -1) {
step[next_down] = step[current] + 1;
q.push(next_down);
}
}
}
int main() {
cin >> n >> A >> B;
k.resize(n + 1);
step.resize(n + 1, -1);
for (int i = 1; i <= n; i++) {
cin >> k[i];
}
bfs();
cout << (step[B] != -1 ? step[B] : -1) << endl;
return 0;
}
在这两种方法中,BFS 用于快速找到从起始点到终点的最短路径,同时避免了重复探索同一个楼层。每到达一个新楼层,我们都更新到达该楼层的步数。如果无法到达
1441. 骑士牛
普通数组
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 155;
char grid[MAXN][MAXN];
bool visited[MAXN][MAXN];
int X, Y;
int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
struct Node {
int x, y, steps;
};
bool isValid(int x, int y) {
return x >= 0 && x < X && y >= 0 && y < Y && grid[y][x] != '*' && !visited[y][x];
}
int bfs(int startX, int startY) {
queue<Node> q;
q.push({startX, startY, 0});
visited[startY][startX] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (grid[current.y][current.x] == 'H') {
return current.steps;
}
for (int i = 0; i < 8; i++) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (isValid(nx, ny)) {
visited[ny][nx] = true;
q.push({nx, ny, current.steps + 1});
}
}
}
return -1; // 如果找不到路径
}
int main() {
cin >> X >> Y;
int startX, startY;
for (int i = 0; i < Y; i++) {
for (int j = 0; j < X; j++) {
cin >> grid[i][j];
if (grid[i][j] == 'K') {
startX = j;
startY = i;
}
}
}
cout << bfs(startX, startY) << endl;
return 0;
}
STL局部变量
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct Node {
int x, y, steps;
};
const int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
const int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int bfs(const vector<string>& grid, int startX, int startY) {
int X = grid[0].size();
int Y = grid.size();
vector<vector<bool>> visited(Y, vector<bool>(X, false));
queue<Node> q;
q.push({startX, startY, 0});
visited[startY][startX] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (grid[current.y][current.x] == 'H') {
return current.steps;
}
for (int i = 0; i < 8; i++) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 0 && nx < X && ny >= 0 && ny < Y && grid[ny][nx] != '*' && !visited[ny][nx]) {
visited[ny][nx] = true;
q.push({nx, ny, current.steps + 1});
}
}
}
return -1;
}
int main() {
int X, Y;
cin >> X >> Y;
vector<string> grid(Y);
int startX, startY;
for (int i = 0; i < Y; i++) {
cin >> grid[i];
for (int j = 0; j < X; j++) {
if (grid[i][j] == 'K') {
startX = j;
startY = i;
}
}
}
cout << bfs(grid, startX, startY) << endl;
return 0;
}
STL全局变量
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct Node {
int x, y, steps;
};
vector<string> grid;
vector<vector<bool>> visited;
vector<int> dx = {-2, -1, 1, 2, 2, 1, -1, -2};
vector<int> dy = {1, 2, 2, 1, -1, -2, -2, -1};
int X, Y;
bool isValid(int x, int y) {
return x >= 0 && x < X && y >= 0 && y < Y && grid[y][x] != '*' && !visited[y][x];
}
int bfs(int startX, int startY) {
queue<Node> q;
q.push({startX, startY, 0});
visited[startY][startX] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (grid[current.y][current.x] == 'H') {
return current.steps;
}
for (int i = 0; i < 8; i++) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (isValid(nx, ny)) {
visited[ny][nx] = true;
q.push({nx, ny, current.steps + 1});
}
}
}
return -1;
}
int main() {
cin >> X >> Y;
grid.resize(Y);
visited.resize(Y, vector<bool>(X, false));
int startX, startY;
for (int i = 0; i < Y; i++) {
cin >> grid[i];
for (int j = 0; j < X; j++) {
if (grid[i][j] == 'K') {
startX = j;
startY = i;
}
}
}
cout << bfs(startX, startY) << endl;
return 0;
}