迷宫(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