HDU 5025 Saving Tang Monk(状态转移, 广搜)
#include<bits/stdc++.h> using namespace std; const int maxN = 107; const int inf = 1e9 + 7; char G[maxN][maxN], snake[maxN][maxN]; int times[maxN][maxN][15]; int n, m, sx, sy, ex, ey, ans; int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; struct node { int x, y, t, key, killed; //坐标, 步数, 已经拿到的钥匙, 有没有杀蛇 bool operator < (const node& p) const { return t > p.t; } node(int x, int y, int t, int key, int killed):x(x),y(y), t(t), key(key), killed(killed) {}; }; void bfs() { node t = (node) { sx, sy, 0, 0, 0 }; times[sx][sy][0] = 0; queue<node> q; q.push(t); while(!q.empty()) { node u = q.front(); q.pop(); int x = u.x, y = u.y, key = u.key, t = u.t, killed = u.killed; if(x == ex && y == ey && key == m) { ans = min(ans, t); continue; } for(int d = 0; d < 4; d++) { int tx = x + dir[d][0]; int ty = y + dir[d][1]; if(tx < 0 || tx >= n || ty < 0 || ty >= n || G[tx][ty] == '#') //越界 continue; if(G[tx][ty] >= '1' && G[tx][ty] <= '9') //如果是钥匙 { int num = G[tx][ty] - '0'; if(key + 1 == num && (times[tx][ty][key + 1] > t + 1)) //可以拿 { q.push(node(tx,ty,t+1,key+1,killed)); times[tx][ty][key + 1] = t + 1; } else if(((key + 1) != num) && (times[tx][ty][key] > t + 1)) //不可以拿 { q.push(node(tx,ty,t+1,key,killed)); times[tx][ty][key] = t + 1; } } else if(G[tx][ty] >= 'A' && G[tx][ty] <= 'E') //蛇 { int cnt = G[tx][ty] - 'A'; //压位判断 if((killed & (1<<cnt)) == 0) //未杀 { if(times[tx][ty][key] > t + 2) { q.push(node(tx,ty,t+2,key,(killed | (1<<cnt)))); times[tx][ty][key] = t + 2; } } else //已经杀了 { if(times[tx][ty][key] > t + 1) { q.push(node(tx,ty,t+1,key,killed)); times[tx][ty][key] = t + 1; } } } else if((G[tx][ty] == '.' || G[tx][ty] == 'T' || G[tx][ty] == 'K') && times[tx][ty][key] > t + 1) { q.push(node(tx,ty,t+1,key,killed)); times[tx][ty][key] = t + 1; } } } } int main() { // freopen("1.txt","r", stdin); while(~scanf("%d %d", &n, &m)) { int cnt = 0; if(n == 0) break; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < 10; k++) times[i][j][k] = inf; for(int i = 0; i < n; i++) { scanf("%s", G[i]); } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(G[i][j] == 'K') sx = i, sy = j; if(G[i][j] == 'T') ex = i, ey = j; if(G[i][j] == 'S') { G[i][j] = (cnt++ + 'A'); } } } ans = inf; bfs(); if(ans == inf) { printf("impossible\n"); } else { printf("%d\n", ans); } } return 0; }