问题描述:
问题分析:给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
测试案例:
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
No
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3
yes*/
解题的思想:利用回溯的方法,对于每一个点都有四个分支,做到心中有“树”;在起点位置,有四种选择,在循环中选择其中的一个点,用OK(y,x)函数来判断遍历的点是否超出迷宫的边界(是否小于0或者大于边界最大值),如果满足条件,在顺着这个点向它的四个分支的某一个分支进行遍历并判断,当走到这个分支的最后一点点,就返回这个点的跟节点,并将数据的值还原为根节点时的状态,再接着去遍历这个根节点另外的子节点。这里边之所以有olddirection是为了避免将重复的点在计入directionCount,maxdirectionCount+1是因为在原始位置出发的第一个点不算是拐弯。
#include <stdio.h>
#define m 5
#define n 5
#define maxdirection 2
#define x1 1
#define y1 1
#define x2 1
#define y2 3
int directionCount=0;
int direction=-1;
int count=0;
int pos[4][2]={0,-1,0,1,-1,0,1,0}; //上下左右
char palace[m][n]={
'.','.','.','*','*',
'*','.','*','*','.',
'.','.','.','.','.',
'.','.','.','.','.',
'*','.','.','.','.'};
bool OK(int y, int x){
if(x<0 || y<0 || x>=m || y>=n || palace[y][x]=='*')
return false;
return true;
}
void traceback(int y, int x)
{
int olddirection;
if(y==y2-1 && x==x2-1){
if(directionCount<=maxdirection+1)
count++;
return;
}
if(directionCount>maxdirection+1)
return;
for(int i=0;i<4;i++){
y+=pos[i][0];
x+=pos[i][1];
olddirection=direction;
if(i!=direction){
directionCount++;
}
direction=i;
if(OK(y,x))
traceback(y,x);
if(direction!=olddirection)
directionCount--;
direction=olddirection;
y-=pos[i][0];
x-=pos[i][1];
}
}
int main(){
traceback(y1-1,x1-1);
if(count>0){
printf("yes\n");
}
else
printf("no\n");
return 0;
}