首页 新闻 会员 周边

bfs求调!

0
悬赏园豆:40 [待解决问题]

这一题
50pts,哪里出问题了?

#include<bits/stdc++.h>
using namespace std;
int m,n,ma[105][105],vis[105][105];
int ans=-1;
int net[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct node{
	int x,y,dis,is_ch,col;
};
int bfs()
{
	int ans=-1;
	queue<node> q;
	q.push((node){1,1,0,0,ma[1][1]});
	vis[1][1]=1;
	while(!q.empty()){
		node u=q.front();
		q.pop();
		vis[u.x][u.y]=1;
		/*if(u.dis>ans){
			q.pop();
			continue;
		}*/
		if(u.x==m&&u.y==m){
			return u.dis;
		/*	ans=min(ans,u.dis);
			q.pop();
			continue;*/
		}
		for(int i =0;i<4;i++){
			int nx=u.x+net[i][0];
			int ny=u.y+net[i][1];
			if(nx<=m&&nx>=1&&ny<=m&&ny>=1&&vis[nx][ny]==0){
				if(ma[nx][ny]==u.col&&ma[nx][ny]!=0){
					q.push((node){nx,ny,u.dis,0,ma[nx][ny]});
					vis[nx][ny]=1; 
				}
				if((ma[nx][ny]==1&&u.col==2)||(ma[nx][ny]==2&&u.col==1)){
					q.push((node){nx,ny,u.dis+1,0,ma[nx][ny]});
					vis[nx][ny]=1; 
				}
				if(ma[nx][ny]==0&&u.is_ch==0) {
					q.push((node){nx,ny,u.dis+2,1,ma[u.x][u.y]});
				    vis[nx][ny]=1; 
					
				}
			}
		}
		
	}
	return ans;
}
int main()
{
	memset(vis,0,sizeof(vis)); 
	memset(ma,0,sizeof(ma));
	scanf("%d%d",&m,&n);
	for(int i = 1;i<=n;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		ma[a][b]=c+1;
	}
	int ans=bfs();
	cout<<ans;
	return 0;
}
全角的!与半角的!的主页 全角的!与半角的! | 初学一级 | 园豆:138
提问于:2023-08-07 13:20
< >
分享
所有回答(1)
0

根据提供的代码,可能会有以下问题导致没有得到期望的结果:

  1. 未正确处理终止条件:当前代码中未正确处理终止条件。当到达目标位置时,虽然返回了 u.dis,但是并没有将其保存在 ans 中。同时,ans 的初始值在 main() 函数中已经被设置为 -1,这可能会导致最终输出 -1。你可以尝试在目标位置找到后将 u.dis 赋值给 ans

  2. 错误的邻居坐标计算:在计算邻居节点的坐标时,使用的是 net 数组来确定偏移量,但是判断邻居节点的合法性时,使用的是 nxny 与边界值比较。这可能会导致越界访问的问题。你可以使用 (nx >= 1 && nx <= m && ny >= 1 && ny <= m) 来判断邻居节点是否在合法范围内。

  3. 未处理重复访问:vis 数组用于标记已经访问过的节点,但是在 bfs() 函数中,没有对重复访问进行处理。这可能导致重复节点多次入队,导致死循环或者重复计算。你可以在将节点加入队列前,检查该节点是否已经被访问过,如果已访问过,则不加入队列。

  4. 初始化数组:在 main() 函数中,使用 memset() 初始化数组 visma。但是由于 ma 数组中存储的是颜色值,可能不会为 0。你可以使用 -1 或其它特殊值来初始化 ma 数组,并在代码中显式处理这些特殊值。

我对代码进行了如下处理:

  1. 修改了输出流为 cincout,这样可以更方便地输入和输出。

  2. 调整了结构体的成员顺序,使其更易读。同时,修正了结构体的初始化方式,用花括号括起来进行初始化。

  3. 修改了 bfs() 函数的返回值,当无法到达终点时返回 -1。之前的代码没有正确返回 -1

  4. 修改了 bfs() 函数中对节点的访问和入队的顺序,保证正确处理节点的访问。

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

const int MAXN = 105;
int m, n;
int ma[MAXN][MAXN];
int vis[MAXN][MAXN];

// 方向数组,表示上下左右四个方向的偏移量
int net[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

struct node{
    int x, y;
    int dis;  // 到达该点的步数
    bool isChange;  // 是否改变颜色
    int col;  // 当前位置的颜色
};

int bfs()
{
    queue<node> q;
    q.push({1, 1, 0, false, ma[1][1]});
    vis[1][1] = 1;

    while (!q.empty()){
        node u = q.front();
        q.pop();

        if (u.x == m && u.y == m){
            return u.dis;
        }

        for (int i = 0; i < 4; i++){
            int nx = u.x + net[i][0];
            int ny = u.y + net[i][1];

            if (nx >= 1 && nx <= m && ny >= 1 && ny <= m && vis[nx][ny] == 0){
                // 如果下一个节点颜色与当前节点颜色相同,在不改变颜色的情况下继续移动
                if (ma[nx][ny] == u.col){
                    q.push({nx, ny, u.dis, false, ma[nx][ny]});
                    vis[nx][ny] = 1;
                }
                // 如果下一个节点颜色与当前节点颜色不同,需要改变颜色,步数加一
                if ((ma[nx][ny] == 1 && u.col == 2) || (ma[nx][ny] == 2 && u.col == 1)){
                    q.push({nx, ny, u.dis + 1, false, ma[nx][ny]});
                    vis[nx][ny] = 1;
                }
                // 如果下一个节点颜色为0,并且当前节点没有改变颜色,则可以改变颜色并继续移动
                if (ma[nx][ny] == 0 && !u.isChange){
                    q.push({nx, ny, u.dis + 2, true, u.col});
                    vis[nx][ny] = 1;
                }
            }
        }
    }

    return -1;  // 无法到达终点
}

int main()
{
    memset(vis, 0, sizeof(vis));
    memset(ma, 0, sizeof(ma));

    cin >> m >> n;
    for (int i = 1; i <= n; i++){
        int a, b, c;
        cin >> a >> b >> c;
        ma[a][b] = c + 1;
    }

    int ans = bfs();
    cout << ans << endl;

    return 0;
}
lanedm | 园豆:2378 (老鸟四级) | 2023-08-08 08:03

感谢!
但还是不对,可能是哪里有逻辑性的问题。

支持(0) 反对(0) 全角的!与半角的! | 园豆:138 (初学一级) | 2023-08-08 08:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册