【HDOJ】3442 Three Kingdoms
bfs+状态压缩。初始化数组的曼哈顿距离条件写错了,改了一下午。
1 /* 3442 */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 using namespace std; 8 9 #define MAXN 55 10 11 typedef struct node_t { 12 int x, y; 13 int s, v; 14 node_t() {} 15 node_t(int xx, int yy, int ss, int vv) { 16 x = xx; y = yy; s = ss; v = vv; 17 } 18 friend bool operator <(const node_t &a, const node_t &b) { 19 return a.v > b.v; 20 } 21 } node_t; 22 23 char map[MAXN][MAXN]; 24 char hurt[MAXN][MAXN][5]; 25 bool visit[MAXN][MAXN][33]; 26 int ls[5] = {2, 3, 0, 2, 1}; 27 int bx, by, ex, ey; 28 int dir[4][2] = { 29 {-1,0},{1,0},{0,-1},{0,1} 30 }; 31 int n, m; 32 33 34 int abs(int x) { 35 return x<0 ? -x:x; 36 } 37 38 bool check(int x, int y) { 39 return x<0 || x>=n || y<0 || y>=m; 40 } 41 42 bool invalid(char ch) { 43 return !(ch=='$' || ch=='!' || ch=='C' || ch=='.'); 44 } 45 46 int Manh(int x0, int y0, int x1, int y1) { 47 return abs(x0-x1) + abs(y0-y1); 48 } 49 50 51 void init() { 52 int i, j, k, h, l; 53 int x, y, z; 54 55 memset(hurt, 0, sizeof(hurt)); 56 for (i=0; i<n; ++i) { 57 for (j=0; j<m; ++j) { 58 if (map[i][j] == '$') { 59 bx = i; 60 by = j; 61 } else if (map[i][j] == '!') { 62 ex = i; 63 ey = j; 64 } else if (map[i][j]=='#' || map[i][j]=='.') { 65 continue; 66 } else if (map[i][j]>='A' && map[i][j]<='E'){ 67 z = map[i][j] - 'A'; 68 h = z + 1; 69 l = ls[z]; 70 for (x=i-l; x<=i+l; ++x) { 71 for (y=j-l; y<=j+l; ++y) { 72 if (check(x, y) || Manh(x,y,i,j)>l) 73 continue; 74 hurt[x][y][z] = h; 75 } 76 } 77 } 78 } 79 } 80 } 81 82 int bfs() { 83 int i, j, k; 84 int x=bx, y=by, s=0, v=0; 85 node_t nd; 86 priority_queue<node_t> Q; 87 88 memset(visit, false, sizeof(visit)); 89 visit[x][y][s] = true; 90 Q.push(node_t(x, y, s, v)); 91 92 while (!Q.empty()) { 93 nd = Q.top(); 94 if (nd.x==ex && nd.y==ey) 95 return nd.v; 96 Q.pop(); 97 for (i=0; i<4; ++i) { 98 x = nd.x + dir[i][0]; 99 y = nd.y + dir[i][1]; 100 s = nd.s; 101 v = nd.v; 102 if (check(x, y) || invalid(map[x][y]) || visit[x][y][s]) 103 continue; 104 visit[x][y][s] = true; 105 for (j=0; j<5; ++j) { 106 k = 1<<j; 107 if (hurt[x][y][j] && (s&k)==0) { 108 v += hurt[x][y][j]; 109 s |= k; 110 } 111 } 112 Q.push(node_t(x, y, s, v)); 113 } 114 } 115 116 return -1; 117 } 118 119 int main() { 120 int t, tt; 121 int i, j, k; 122 123 #ifndef ONLINE_JUDGE 124 freopen("data.in", "r", stdin); 125 #endif 126 127 scanf("%d", &t); 128 for (tt=1; tt<=t; ++tt) { 129 scanf("%d %d", &n, &m); 130 for (i=0; i<n; ++i) 131 scanf("%s", map[i]); 132 init(); 133 k = bfs(); 134 printf("Case %d: %d\n", tt, k); 135 } 136 137 return 0; 138 }