洛谷原题

图论题。

题目要求棋子从左上角走到右下角的最短路。

1 DFS

先考虑用深度优先搜索解决。

注意:我们要判断一下相邻两步的格子颜色,这也决定了下一步的合法性。

可以写出以下核心代码:

void dfs(int x,int y,char c,int step){//x 和 y 表示当前位置,c 表示当前格的颜色,step 表示步数
    if(x==n&&y==m){//搜到终点
        ans=min(ans,step);//更新答案
        return ;
    }
    vis[x][y]=1;
    for(int i=0; i<4; i++){
        int tx=x+dx[i],ty=y+dy[i];
        if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&!vis[tx][ty]&&maze[tx][ty]!=c){//判断下一个位置是否合法
            dfs(tx,ty,maze[tx][ty],step+1);
            vis[tx][ty]=0;//回溯
        }
    }
}

这是过不了的。

TLE 记录

2 BFS

超时了。再改一改,用广度优先搜索解。要注意的点同上。

这样就可以 AC 了。

AC 记录

AC 代码

#include<bits/stdc++.h>
using namespace std;
int dx[]={0,1,-1,0},dy[]={1,0,0,-1};
int n,m;
int dis[505][505];
char maze[505][505];
struct node{
    int o,p;
    char w;
};//存储状态
void bfs(){
    memset(dis,0x3f,sizeof(dis));
    queue<node> q;
    dis[1][1]=0;
    q.push({1,1,maze[1][1]});
    while(!q.empty()){
        node now=q.front();//当前状态
        q.pop();
        int x=now.o,y=now.p;
        char c=now.w;
        if(x==n&&y==m){
            return;//搜到终点,结束
        }
        for(int i=0; i<4; i++){
            int tx=x+dx[i],ty=y+dy[i];
            if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&dis[tx][ty]>dis[x][y]+1&&maze[tx][ty]!=c){//判断下一个位置是否合法
                q.push({tx,ty,maze[tx][ty]});
                dis[tx][ty]=dis[x][y]+1;//更新最短路
            }
        }
    }
    
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            cin>>maze[i][j];
        }
    }
    bfs();
    if(dis[n][m]==0x3f3f3f3f) printf("-1");//无解
    else printf("%d",dis[n][m]);
    return 0;
}

3 补充

其实这道题还挺模板的。适合广度优先搜索新手练习。

推荐一些广度优先搜索题目:

posted on 2026-06-29 21:41  lz5332t  阅读(2)  评论(0)    收藏  举报