NYOJ--58题最少步数

9 篇文章 0 订阅
5 篇文章 0 订阅

这个题AC了很久,本来不想贴这串代码的,但是最近要学习搜索。这个题算是搜索中很简单的存在了,当初学长也是把这个题当作例题给我们讲解的。现在觉得把它贴出来吧,能够让其他人参考一下思路,可能有很大的收获。这个星期一直在弄动态规划,不想在弄01背包了。这两天还是弄搜索吧,在加深一下认识。也跟得上进度,虽然我是最弱的一个。

解题思路:根据题目中给定的坐标,你需要做的就是判断由起始点走到终点的最小步数。基本的理念就是你建立一个结构体(或者二维数组)进行标记,从一个点出发,向四个方向前进,如果能走,就把这个点放入栈中,否者舍弃。不断的重复,不断的判断,直到到达重点或者走不出去。

原题地址:点击打开链接

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int a[9][9]={
1,1,1,1,1,1,1,1,1,
1,0,0,1,0,0,1,0,1,
 1,0,0,1,1,0,0,0,1,
 1,0,1,0,1,1,0,1,1,
 1,0,0,0,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,0,0,0,1,
 1,1,1,1,1,1,1,1,1
};//题目中的数据
int b[4][2]={-1,0,1,0,0,-1,0,1};//标记上下左右四个坐标
int visit[9][9];//标记足迹
struct num 
{
	int x,y,step;
};
queue<num> Q;//建立一个Q队列
int bfs(int x1,int y1,int x2,int y2)
{
	int i,s,t;
	num e={x1,y1,0};//储存一下
	Q.push(e);//放入队列
	visit[x1][y1]=1;//标记此处已经走过。
	while(!Q.empty())//当队列不为空,
	{
		e=Q.front();//e是队首
		if(e.x==x2&&e.y==y2)//判断是否走到了目的地。
			break;
		Q.pop();//删除队首
		for(i=0;i<4;i++)//此处就是进行判断四个方向是否可行。 
		{
			s=e.x+b[i][0];
			t=e.y+b[i][1];
			if(s>=0&&s<=8&&t>=0&&t<=8&&!visit[s][t]&&a[s][t]==0)//判断边界
			{
				num e1={s,t,e.step+1};
				Q.push(e1);
				visit[s][t]=1;
			}
		}

	}
	if(Q.empty())return -1;//此时表示的是陷入了死胡同,无路可走。不过题目中没有提到这个情况,所以下面没有进行讨论。
	while(!Q.empty())//清空整个队列
		Q.pop();
	return e.step;
}
int main()
{
	int n,x1,y1,x2,y2,k;
	cin>>n;
	while(n--)
	{
		cin>>x1>>y1>>x2>>y2;
		memset(visit,0,sizeof(visit));//每次都清除足迹。
		k=bfs(x1,y1,x2,y2);
		cout<<k<<endl;
	}
	return 0;
}

如果一个问题做过之后不及时的复习一下的话,那么下次在看到同类问题的时候你就需要花费很长时间去回忆,去思考。所以经常复习一下以前的东西是一个不错的习惯。所以这篇日志不只是写给那些刚接触搜索的童鞋看的,同时也是写给自己的。

路漫漫其修远兮,吾将上下而求索!

加油吧,跟我一样的小菜鸟们!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值