浅析搜索(search)NO.4

迷宫(3):

 

【题目部分】

有一个mn格的迷宫(表示有m行、n列),其中有可走的也有不可走的,如果用0表示可以走,1表示不可走,文件读入这mn个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的的行号和列号)。现在要你编程找出从起点到终点的最少步数和最少步数的总走法,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出“No Answer! ”。

Input

 

第一行是两个数 m、n,接下来是m行n列由10组成的数据,最后两行是起始点(X1,X2)和结束点(Y1,Y2)。

数据范围:0 < M,N <= 2000 , 0〈 X1,X2〈= N,0〈 Y1,Y2〈= M。

 

Output

 

一行两个数,表示最少步数和最少步数走法总数。如果走不到,则输出“No Answer! ”

 

Sample Input 1

3 5

0 0 0 0 0 

0 1 0 1 0

0 0 0 0 0

1 1

3 5



Sample Output 1

6 3

Hint

输出说明:

最少需要6步到达结束点。

总共三种6步的走法。

                                                                                                                      ——摘自学校OJ

刚刚做完迷宫(2)不想写迷宫(2)的题解,因为懒qwq,学了一下广度优先搜索(不知道的看着广搜),看到这题我的思路是:先广搜找到最少步数,然后用深搜穷举每条路的到达终点的步数,如果和最少步数相同,就把方案数+1。

 

代码实现:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
bool walk[2011][2011]={0},ma[2011][2011],w[2011][2011];
int dx[]={0,0,1,-1},dy[]={-1,1,0,0};
struct node{
	ll x,y,step;
};
queue<node> q;//queue即队列,负责广搜
node temp,s,e,x,t;
ll N,M;
bool bj=1;
ll ans=0,walker;
void dfs(ll X,ll Y,ll js){
	if(X==e.x&&Y==e.y){
		if(js==ans){
			walker++;
			return ;
		}
		else
			return ;
	}
	else{
	    ...
	}
	return ;
}
int main(){
	memset(walk,1,sizeof(walk));
	memset(w,1,sizeof(w));
	cin>>N>>M;
	for(int i=1;i<=N;i++){
		for(int j=1;j<=M;j++){
			cin>>walk[i][j];
			w[i][j]=walk[i][j];
		}
	}
	cin>>s.x>>s.y>>e.x>>e.y;
	s.step=0;
	q.push(s);
	while(!q.empty()){
		t=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			temp.x=t.x+dx[i];
			temp.y=t.y+dy[i];
			temp.step=t.step+1;
			if(walk[temp.x][temp.y]==0){
				walk[temp.x][temp.y]=1;
				if(temp.x==e.x&&temp.y==e.y){
					ans=temp.step;
					break;
				}
				else
					q.push(temp);
			}
		}
	}
	if(ans==0){
		cout<<"No Answer!";
		return 0;
	}
	dfs(s.x,s.y,0);
	if(ans!=0){
		cout<<ans<<" "<<walker;
	}
	return 0;
}

提交以后发现,有个点TLE了,想了想应该是广搜部分找到最优解后没有及时退出的原因,我就又改了一下:

while(!q.empty()){
		t=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			temp.x=t.x+dx[i];
			temp.y=t.y+dy[i];
			temp.step=t.step+1;
			if(walk[temp.x][temp.y]==0){
				walk[temp.x][temp.y]=1;
				if(temp.x==e.x&&temp.y==e.y){
					ans=temp.step;
					bj=0;
					break;
				}
				else
					q.push(temp);
			}
		}
		if(!bj)
			break;
	}//bj负责查看是否已找到最优解

再提交了一下,又双叒叕TLE了,仔细一想,深搜部分剪枝没用上!

于是乎:

inline void dfs(ll X,ll Y,ll js){
	if(js>ans)
		return ;
	if(X==e.x&&Y==e.y){
		if(js==ans){
			walker++;
			return ;
		}
		else
			return ;
	}
	else{
		.......
	}
	return ;
}

直接莽一波,提交!

AC了qwq

主要框架都在上方,如何补全代码就看你了↖(^ω^)↗

                                                                                      ——溜了溜了qwq

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值