递归例题讲解 一本通1215:迷宫 答案解析
自己做法,不喜勿喷,仅供参考
时间限制: 1000 ms 内存限制: 65536 KB
【题目描述】
一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n×n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。
【输入】
第1行是测试数据的组数k,后面跟着k组输入。每组测试数据的第1行是一个正整数n(1≤n≤100),表示迷宫的规模是n×n的。接下来是一个n×n的矩阵,矩阵中的元素为.或者# 。再接下来一行是4个整数ha,la,hb,lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha,la,hb,lb全部是从0开始计数的。
【输出】
k行,每行输出对应一个输入。能办到则输出YES,否则输出“、NO。
答案分析
很显然这道题需要用深搜或广搜 但是深搜比较好写
按照常规思路,不断试就行。但是要防止超时,因为深搜的死循环是很恐怖的…于是需要一个放超时的机制,这里我用了两个方法:超时判断和堵死后路。
放超时措施
超时判断
定义一个timeout变量,为函数的递归极限次数,防止死循环无限膨胀。
int timeout=10000000;
同时在每次循环的时候判断是否超时达到杀进程的方法
if(time>timeout)
return 0;
堵死后路
把走过的路变成墙,防止又走一遍回头路
if(mapp[hn][ln]=='#')
return 0;
else
mapp[hn][ln]='#';
整体理解
mapp是地图存储。
void beginn()是程序主体部分,包含了循环。
bool panding()是封装完毕的解决方法
void inputMap()是录入地图
bool digui(int hn,int ln,int time)解决方法
递归思想
就是四个方向到处走,不停的试
答案
#include <iostream>
using namespace std;
string mapp[101];
int n=0,k=0;
int la,ha,lb,hb;
int timeout=10000000;
void inputMap(){
cin>>n;
for(int i=0;i<n;i++){
cin>>mapp[i];
}
cin>>ha>>la>>hb>>lb;
}
bool digui(int hn,int ln,int time){
if(hn>=n||ln>=n||hn<0||ln<0)
return 0;
if(time>timeout)
return 0;
if(mapp[hn][ln]=='#')
return 0;
else
mapp[hn][ln]='#';
time++;
bool a,b,c,d;
a=digui(hn+1,ln,time);
b=digui(hn-1,ln,time);
c=digui(hn,ln+1,time);
d=digui(hn,ln-1,time);
return a||b||c||d;
}
bool panding(){
digui(ha,la,0);
if(mapp[hb][lb]=='#')
return 1;
else
return 0;
}
void beginn(){
cin>>k;
for(int i=0;i<k;i++){
inputMap();
if(panding()){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}
}
}
int main(int argc, char** argv) {
beginn();
return 0;
}