Question:
A person takes the paper box to his destination. Under normal circumstances, one second can walk in a grid without moving it in the box. The principle is that he cannot walk through the wall and some lights on the map can shine on himself. and in front of a grid, the light turns clockwise for 90 degrees every second. If you want to exit from the place where the light is taken or enter the place where the light is taken, you must put it in a box and ask the shortest time to the destination.
Ideas:
The status is only 500*500 (map size) * 4 (four directions for light conversion). You can use the priority queue in BFs.
Code:
#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 510int 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;elsev.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 5040 instrusive