假设有一个矩阵,四个边都是堵住的,矩阵内部有若干障碍物,现在有两个点,用若干条直线连接两个点,且直接不能穿越障碍物,那么至少需要几条直线呢?
前面写过一个迷宫中求路径的程序( http://blog.youkuaiyun.com/royt/article/details/74848796 ),用到了递归的方式求解。先用类似的方法定义一个满足要求的矩阵。对于迷宫的矩阵,四个边都布满了障碍物且分别有一个入口和出口位于其上,在这个问题里面我们可以简化一下去掉四边的围墙,反正寻找路径时坐标点满足 0<=x<HEIGHT 和 0<=y<WIDTH 即可。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
// height & width must be positive ingeters and cannot both be 1
#define HEIGHT 24
#define WIDTH 36
// 2-dimensional array that represents the maze
int matrix[HEIGHT][WIDTH];
int min_nLines = INT_MAX;
// 4 directions: {right, down, left, up}
const int DIRECTIONS[4][2] = {
{0,1}, {1,0}, {0,-1}, {-1,0}};
// status of a cell in the matrix
enum status { BLOCKED = -1, START = 0, UNBLOCKED = INT_MAX - 1, END = INT_MAX };
同样定义了寻找路径的四个方向,矩阵上每个点的状态要么为障碍(-1),要么为空白格(极大值),在计算之后其值更新为到达起点的步数(也就是连通所需的最小直线数量)。那么对于起始点,这个值当然为0,对于其他空白和终点,可以先设置一个非常大的正整数,为了表示区别将终点设置为INT_MAX,其他空白为INT_MAX - 1。接下来则是生成矩阵的程序,没啥特别之处,先是放置障碍物的函数,其参数定义了空白和障碍物的比例,这个值太小则可能彻底堵死找不到通路,太大则显得矩阵空空荡荡,连通的路径不够百曲千回,演示效果不佳,一般取3或4就差不多了。接着是随机选取起点和终点,两点不允许重合,为了简单起见,即使不小心选到障碍物也不用计较,就当它原本是空白格。最后是打印矩阵,可以人为的给四周加上一圈围墙,每一处空白会显示为距离起点的步数(当然有些空白是不可达的,假如正好被障碍物围起来)。这一切看来都没什么问题。
void placeObstacle(int