华为机试 第二题-速战速决

这篇博客介绍了如何使用C++实现一个基于深度优先搜索(DFS)解决迷宫问题的算法。作者通过两段代码展示了两种不同的实现方式,一种是基本的DFS,另一种是优化后的DFS结合记忆化搜索。在代码中,作者处理了越界、特殊条件检查以及操作方向的逻辑。最后,代码会输出从起点到终点的最短步数,如果没有路径则输出-1。
摘要由CSDN通过智能技术生成

9月7号 第二题速战速决

虽然g了,但还是写出了,差一点啊,难过。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>

using namespace std;

vector<vector<bool>> visited;
int min_time = INT32_MAX;
vector<pair<int, int>> off_set {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};

bool ischange(vector<vector<char>> &streets, int r1, int c1, int r2, int c2, int op) {
	//op == 1  遂平
	//op == 0 竖直
	if (op == -1)
		false;
	if (op == 0 && r1 == r2)
		return true;
	if (op == 1 &&  c1 == c2)
		return true;
	return false;

}

void dfs(vector<vector<char>> &streets, int row, int colum, int time, int op) {
	cout << time << endl;
	if (streets[row][colum] == 'E') {
		min_time = min(min_time, time);
		return ;

	}
	for (auto &off : off_set) {
		int r = row + off.first;
		int c = colum + off.second;
		if (r < 0 || r >= streets.size() || c < 0 || c >= streets[0].size() ) {
			continue;
		}
		if (visited[r][c])
			continue;
		if (streets[r][c] == 'X')
			continue;
		visited[r][c] = true;
		bool changed = ischange(streets, row, colum, r, c, op);
		int new_op;
		if (changed && op == 1)
			new_op = 0;
		else if (changed && op == 0) 
			new_op = 1;
		else if (op == -1 && r > 1)
			new_op = 0;
		else if (op == -1 && c > 1)
			new_op = 1;
		else
			new_op = op;
		dfs(streets, r, c, (changed ? time+2 : time+1), new_op);
		visited[r][c] = false;
	}
}


int main() {
	int M;
	int N;
	cin >> M >> N;
	vector<vector<char>> streets(M, vector<char>(N));
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < N; ++j) {
			cin >> streets[i][j];
		}
	}
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < N; ++j) {
			cout << streets[i][j] << " ";
		}
		cout << endl;
	}
	visited = vector<vector<bool>>(M, vector<bool>(N, false));
	int r;
	int c;
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < N; ++j) {
			if (streets[i][j] == 'S') {
				r = i;
				c = j;
				break;
			}
		}
	}
	dfs(streets, r, c, 0, -1);
	if (min_time == INT32_MAX)
		cout << -1 << endl;
	else
		cout << min_time << endl;





	return 0;

}

反思一下:
1.出现段错的时候应该,抓紧启动调试,而不是傻傻的进行静态分析。
2.要先处理越界,再处理特殊情况
3.|| 运算符是全部都试一遍的,这跟&& 不同。

更新:时间复杂度更低的解法

//dfs+记忆化搜索
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>

using namespace std;

vector<vector<bool>> visited;
vector<vector<int>> g_catch;
vector<pair<int, int>> off_set {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};

bool ischange(vector<vector<char>> &streets, int r1, int c1, int r2, int c2, int op) {
	//op == 1  遂平
	//op == 0 竖直
	if (op == -1)
		false;
	if (op == 0 && r1 == r2)
		return true;
	if (op == 1 &&  c1 == c2)
		return true;
	return false;

}

//将dfs的返回值定义为到达E所在街区的最小时间
int dfs(vector<vector<char>> &streets, int row, int colum, int op) {
	cout << row << " " << colum << endl;
	if (streets[row][colum] == 'E') {
		return 0;

	}
	if (g_catch[row][colum] != -1)
		return g_catch[row][colum];

	int min_time = INT16_MAX;
	for (auto &off : off_set) {
		int r = row + off.first;
		int c = colum + off.second;
		if (r < 0 || r >= streets.size() || c < 0 || c >= streets[0].size() ) {
			continue;
		}
		if (visited[r][c])
			continue;
		if (streets[r][c] == 'X')
			continue;
		visited[r][c] = true;
		bool changed = ischange(streets, row, colum, r, c, op);
		int new_op;
		if (changed && op == 1)
			new_op = 0;
		else if (changed && op == 0) 
			new_op = 1;
		else if (op == -1 && r > 1)
			new_op = 0;
		else if (op == -1 && c > 1)
			new_op = 1;
		else
			new_op = op;
		int t = dfs(streets, r, c, new_op);
		int needtime = changed ? t + 2 : t + 1;
		min_time = min(min_time, needtime);
		visited[r][c] = false;
	}
	g_catch[row][colum] = min_time;
	return min_time;

}


int main() {

	int M = 6;
	int N = 6;
	vector<vector<char>> streets {{'S', 'B', 'B', 'B', 'B', 'B'},
	                              {'B', 'X', 'X', 'X', 'X', 'B'},
								  {'B', 'B', 'X', 'B', 'B', 'B'},
								  {'X', 'B', 'B', 'X', 'X', 'B'},
								  {'B', 'B', 'B', 'B', 'X', 'B'},
								  {'B', 'B', 'X', 'B', 'E', 'B'}};

	visited = vector<vector<bool>>(M, vector<bool>(N, false));
	g_catch = vector<vector<int>>(M, vector<int>(N, -1));
	int r;
	int c;
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < N; ++j) {
			if (streets[i][j] == 'S') {
				r = i;
				c = j;
				break;
			}
		}
	}
	// cout << r << c << endl;
	int ans = dfs(streets, r, c, -1);
	if (ans == INT16_MAX)
		cout << -1 << endl;
	else
		cout << ans << endl;

	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值