HDU 1010 Tempter of the Bone

题目链接:HDU 1010 Tempter of the Bone

题目大意:
一个大小为(N imes M)的迷宫中有一扇门,一开始门是关着的,它会在第(t)秒的时间打开。因此,小明和朋友必须在第(t)秒到大门口。每一秒,他都可以向上下左右四个方向移动一个点。一旦他移动了,他刚才所在的点就消失(这意味着他不能回到他已经走过的点),他不能在一个点上停留超过一秒,并且不能走障碍点,问小明和朋友能否安全逃出。

题解:
看题目就想到搜索,如果不做剪枝会超时,对于还没到开门时间,但已经经过门的情况,没必要再走下去,所以排除这些情况。

#include <iostream>
#include <cstring>
using namespace std;
#define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define ms(a, b) memset(a, b, sizeof(a))

char mat[10][10];
int n, m, t;
int sx, sy, tx, ty;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool flag, use[10][10];

void dfs(int step, int x, int y) {
	if (step == t) {
		if (x == tx && y == ty) {
			flag = true;
			return;
		} else {
			return;
		}
	}
	if (use[tx][ty]) { // 没必要再走下去
		return;
	}
	for (int i = 0; i < 4; ++i) {
		if (flag) {
			return;
		}
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (!use[nx][ny] && nx >= 1 && ny >= 1 && nx <= n && ny <= m && mat[nx][ny] != 'X') {
			use[nx][ny] = true;
			dfs(step + 1, nx, ny);
			use[nx][ny] = false;
		}
	}
}

int main() {
	io_speed_up;
	while (cin >> n >> m >> t) {
		if (!n && !m && !t) {
			break;
		}
		ms(use, 0);
		for (int i = 1; i <= n; ++i) {
			for (int j = 1; j <= m; ++j) {
				cin >> mat[i][j];
				if (mat[i][j] == 'S') {
					sx = i, sy = j;
				}
				if (mat[i][j] == 'D') {
					tx = i, ty = j;
				}
			}
		}
		flag = false;
		use[sx][sy] = true;
		dfs(0, sx, sy);
		if (flag) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/IzumiSagiri/p/13836649.html