HDU 5040 Instrusive

题意:

一个人拿着纸盒子往目的地走  正常情况下一秒走一格  可以原地不动躲在盒子里  也可以套着盒子三秒走一格  走路的原则是不能穿墙  而且地图上有些灯  灯能照到自己和面前一个格  每一秒灯顺时针转90度  如果要从灯照的地方离开或者进入灯照的地方就必须套上盒子  问  最短多长时间到目的地

思路:

状态只有500*500(地图大小)*4(灯转的4个方向)个  暴搜即可  bfs时候要利用优先队列

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cassert>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define N 510

int maz[N][N], dir[4][2] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
int dp[N][N][4];
int T, t, n, Sx, Sy, Ex, Ey;
struct node {
	int x, y, t;
	bool operator<(const node ff) const {
		return t > ff.t;
	}
} u, v;

priority_queue<node> qu;

void bfs() {
	int i, j, flag, x, y;
	memset(dp, -1, sizeof(dp));
	dp[Sx][Sy][0] = 0;
	while (!qu.empty())
		qu.pop();
	u.x = Sx, u.y = Sy, u.t = 0;
	qu.push(u);
	while (!qu.empty()) {
		u = qu.top();
		qu.pop();
		v = u;
		v.t++;
		if (dp[v.x][v.y][v.t % 4] == -1 || dp[v.x][v.y][v.t % 4] > v.t) {
			dp[v.x][v.y][v.t % 4] = v.t;
			qu.push(v);
		}
		for (i = 0; i < 4; i++) {
			v.x = u.x + dir[i][0], v.y = u.y + dir[i][1];
			if (maz[v.x][v.y] != -1) {
				flag = 0;
				if (maz[v.x][v.y] > 0)
					flag = 1;
				if (maz[u.x][u.y] > 0)
					flag = 1;
				for (j = 0; j < 4; j++) {
					x = u.x + dir[j][0], y = u.y + dir[j][1];
					if (maz[x][y] > 0) {
						if (((maz[x][y] - 1 + u.t) % 4) == ((j + 2) % 4)) {
							flag = 1;
							break;
						}
					}
					x = v.x + dir[j][0], y = v.y + dir[j][1];
					if (maz[x][y] > 0) {
						if (((maz[x][y] - 1 + u.t) % 4) == ((j + 2) % 4)) {
							flag = 1;
							break;
						}
					}
				}
				if (flag)
					v.t = u.t + 3;
				else
					v.t = u.t + 1;
				if (dp[v.x][v.y][v.t % 4] == -1
						|| dp[v.x][v.y][v.t % 4] > v.t) {
					dp[v.x][v.y][v.t % 4] = v.t;
					qu.push(v);
				}
			}
		}
	}
}

int main() {
	int i, j;
	char fmaz[N];
	scanf("%d", &T);
	for (t = 1; t <= T; t++) {
		scanf("%d", &n);
		memset(maz, -1, sizeof(maz));
		for (i = 1; i <= n; i++) {
			scanf("%s", fmaz + 1);
			for (j = 1; j <= n; j++) {
				if (fmaz[j] == '#')
					continue;
				maz[i][j] = 0;
				if (fmaz[j] == 'N')
					maz[i][j] = 1;
				else if (fmaz[j] == 'E')
					maz[i][j] = 2;
				else if (fmaz[j] == 'S')
					maz[i][j] = 3;
				else if (fmaz[j] == 'W')
					maz[i][j] = 4;
				else if (fmaz[j] == 'M') {
					Sx = i, Sy = j;
				} else if (fmaz[j] == 'T') {
					Ex = i, Ey = j;
				}
			}
		}
		bfs();
		j = -1;
		for (i = 0; i < 4; i++) {
			if (dp[Ex][Ey][i] != -1 && (j == -1 || j > dp[Ex][Ey][i]))
				j = dp[Ex][Ey][i];
		}
		printf("Case #%d: %d\n", t, j);
	}
	return 0;
}


你可能感兴趣的:(搜索,HDU)