题目:
给定一个二维数组,数字表示海拔高度,输入起始点和终点,判断从起始点能否达到终点?
条件:
1. 搜寻过程,每次只能移动一步,步长为1,且海拔为0的点才能作为搜寻经过的路线
2. 搜寻过程中,直角拐弯(90度)次数不能超过K次, K=2
例子:
矩阵matrix=[
[1 0 5 5]
[3 0 0 3]
[5 7 0 1]
]
起点:(0,0), 终点:(2,3)
输出:
No
解题思路:
(1)路径搜索,用回溯算法,必须定义访问数组vis
(2)搜寻方向:水平方向和竖直方向
(3)搜寻出现拐弯的条件:上次搜寻方向和这次搜寻方向不在一个方向即可:
水平+竖直,或竖直+水平
定义一个int型标记pre_dir,-1代表水平方向,0代表初始时,1代表竖直方向,它代表上次搜寻方向,与当前搜寻方向now_dir比较:
情况1:pre_dir和now_dir在同一方向,不用拐弯
情况2:pre_dir和now_dir在不同方向,拐弯,统计++
情况2:pre_dir = 0时,表示刚开始搜索,不用拐弯
代码如下:
/*
* CPlusPlus online programming website: http://cpp.sh/
*/
#include <iostream>
#include <vector>
using namespace std;
//定义拐弯(90度)处数限制,不超过K次
#define K 2
//用来统计<pre, now, next> 三种连续位置的拐弯次数,分三种情况
int helper(int pre_dir, int now_dir, int cnt) {
int val = pre_dir * now_dir;
//情况1
if (val > 0) //说明上次和这次在相同方向,如只沿着水平方向移动(或竖直方向),此时没有直角拐弯,而是在同一条线上搜寻
return cnt;
//情况2:
if (val < 0) //说明上次和这次在不同方向,此时发生新的直角拐弯, 统计++
return cnt + 1;
//情况3:
return cnt;
}
bool CanCross(vector<vector<int>> const& matrx, int x0, int y0, int x, int y, int xx, int yy, vector<vector<int>>& vis, int pre_dir, int cnt) {
if (x == xx && y == yy && cnt <= K) return true; //到达终点且拐歪次数没超
if (x < 0 || x >= matrx.size() || y < 0 || y >= matrx[0].size() || vis[x][y] || matrx[x][y] && !((x0 == x) && (y0 == y)) || cnt > K ) {
//cout << endl << x << "," << y << " InValid!\n";
return false;
}
vis[x][y] = 1; //回溯数组处理
if (CanCross(matrx, x0, y0, x-1, y, xx, yy, vis, -1, helper(pre_dir, -1,cnt)) ||
CanCross(matrx, x0, y0, x+1, y, xx, yy, vis, -1, helper(pre_dir, -1,cnt)) ||
CanCross(matrx, x0, y0, x, y+1, xx, yy, vis, 1, helper(pre_dir, 1,cnt)) ||
CanCross(matrx, x0, y0, x, y-1, xx, yy, vis, 1, helper(pre_dir, 1,cnt)))
return true;
vis[x][y] = 0; 回溯数组复原
return false;
}
int main()
{
vector<vector<int>> matrix = {
{1,0,5,5},
{3,0,0,3},
{5,7,0,1}
};
/*for (auto r : matrix) {
for (auto l : r)
cout << l << " ";
cout << endl;
}*/
int x0 = 0;
int y0 = 0;
int x1 = 2;
int y1 = 3;
if (matrix[x0][y0] != matrix[x1][y1]) {
cout << "No";
} else {
vector<vector<int>> vis(matrix.size(), vector<int>(matrix[0].size(), 0));
if (CanCross(matrix, x0, y0, x0, y0, x1, y1,vis, 0, 0))
cout << "YES";
else
cout << "No";
}
return 0;
}