试题 算法提高 学霸的迷宫(BFS)

用的是c++,c语言也能懂

先放题目吧(题目直接截图了嘿嘿嘿,方便快捷)

样例输入

Input Sample 1:
3 3
001
100
110

Input Sample 2:
3 3
000
000
000

样例输出

Output Sample 1:
4
RDRD

Output Sample 2:
4
DDRR

数据规模和约定

  有20%的数据满足:1<=n,m<=10
  有50%的数据满足:1<=n,m<=50
  有100%的数据满足:1<=n,m<=500。

  • 思路

        这题是bfs的模板,状态转移是上下左右四个方向,套用一个循环,满足条件的入队列,有什么条件呢?第一个条件是下一步要走的地方没有障碍,也就是非‘1’(对应代码mazz[t1][t2]!='1');第二个条件是每一次上下左右都要保证在0~n和0~m的范围内(WA了一次后才发现这个问题呀呀呀);然后我对每一次搜素都做了标记(vis[][]标记数组),这样搜到的以后在遇到就避免重复判断。

       这题我觉得比较新颖的是还要输出路径,当时也只是套完板子再来思考这个问题的,方法有很多,但我觉得string是真的简洁方便。只要在结构体里多加一个string,每一步都多加一个方向(方向的顺序按字典序排列,一旦找到目标位置,直接结束输出一定就是满足题意得答案),没错string可以直接做加法处理,结果就是把你加上得字符加到原来得字符串里,这是这题里学到得新知识嘿嘿嘿!

下面直接贴源代码。


#include<bits/stdc++.h>
using namespace std;

int n,m;
char mazz[550][550];
int vis[550][550];
int dx[4]={1,0,0,-1};
int dy[4]={0,-1,1,0};
char r[10]={'D','L','R','U'};

struct pos{
	int row;
	int col;
	int step;
	string s;
};

void bfs()
{
	pos cur,now;
	cur.s="";
	cur.row=1;
	cur.col=1;
	vis[1][1]=1;
	cur.step=0;
	queue<pos> q;
	q.push(cur);
	while(!q.empty())
	{
		cur=q.front();
		q.pop(); 
		if(cur.row==n && cur.col==m)
		{
			cout<<cur.step<<endl;
			cout<<cur.s;
			return ;
		}
		
		for(int i=0;i<4;i++)
		{
			int t1=cur.row+dx[i];
			int t2=cur.col+dy[i];
			if((t1>=1&&t1<=n) && (t2>=1&&t2<=m) && mazz[t1][t2]!='1' && vis[t1][t2]==0)
			{
				vis[t1][t2]=1;
				now.row=t1;
				now.col=t2;
				now.step=cur.step+1;
				now.s=cur.s+r[i];
				q.push(now);
			}
		}	
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
        {
    	    cin>>mazz[i][j];
            if(mazz[i][j]=='1') vis[i][j]=1;
      	}
	}
    bfs();
    return 0; 
}


  • 总结

        如果不懂bfs,建议先去从简单的题目入手,比如洛谷里“奇怪的电梯”那道题,更便于理解,然后懂了再做提升,其实区别也就是状态转移的方向变多了,对于初学可能会一下子接受不了。然后是做题不仅只是追求AC通过,而是在练题的这个过程中不断学习更简便的方法,锻炼自己的思维,提升代码能力和思考问题解决问题的效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值