宽搜,根据K的个数判断状态,需要注意的一点是遇到转向点后转向不影响原来的步数
#include<cstdio> #include<algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int MAXN = 205; const int MAXK = 130; char vis[MAXN][MAXN][MAXK]; char mmp[MAXN][MAXN]; #define BORD '0' #define NO '1' #define YS '2' const int dir[4][2] = { 1,0, -1,0, 0,1, 0,-1 }; struct _state { int x, y, k, stp; _state(int xx, int yy, int kk, int ss) { x = xx; y = yy; k = kk; stp = ss; } _state(){} }q[MAXN*MAXN*MAXK]; int n, m, nkey, mxk, bg, ed; int sx, sy, ex, ey, dkey[MAXN][MAXN]; int isfnd, res; void m_search(_state st) { int x, y; for (int i = 0; i< 4; ++i) { _state tp = st; int ax = dir[i][0], ay = dir[i][1]; int flg = 1; while (flg) { x = tp.x+ax; y = tp.y+ay; if (vis[x][y][0] == BORD) break; // 边界 switch (mmp[x][y]) { case '#': if (vis[tp.x][tp.y][tp.k] == YS) { flg = 0; break; } vis[tp.x][tp.y][tp.k] = YS; if (tp.x!=st.x||tp.y!=st.y) q[ed++] = _state(tp.x, tp.y, tp.k, tp.stp+1); flg = 0; break; case 'E': if (tp.k == mxk) { res = tp.stp+1; isfnd = 1; flg = 0; } break; case 'K': tp.k |= 1<<dkey[x][y]; break; case 'U': if (vis[x][y][tp.k]==YS) { flg = 0; break; } ax = dir[1][0]; ay = dir[1][1]; vis[x][y][tp.k] = YS; break; case 'D': if (vis[x][y][tp.k]==YS) { flg = 0; break; } ax = dir[0][0]; ay = dir[0][1]; vis[x][y][tp.k] = YS; break; case 'L': if (vis[x][y][tp.k]==YS) { flg = 0; break; } ax = dir[3][0]; ay = dir[3][1]; vis[x][y][tp.k] = YS; break; case 'R': if (vis[x][y][tp.k]==YS) { flg = 0; break; } ax = dir[2][0]; ay = dir[2][1]; vis[x][y][tp.k] = YS; break; } tp.x = x; tp.y = y; } } } void bfs() { mxk = (1<<nkey)-1; res = -1; bg = ed = 0; isfnd = 0; q[ed++] = _state(sx,sy,0,0); _state tp; while (bg<ed && !isfnd) { tp = q[bg++]; m_search(tp); } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif while (scanf("%d%d", &n, &m)!=EOF) { memset(vis, BORD, sizeof vis); nkey = 0; for (int i = 1; i<= n; ++i) { scanf("%s", mmp[i]+1); for (int j = 1; j<= m; ++j) { memset(vis[i][j], NO, MAXK); if (mmp[i][j] == 'S') sx=i,sy=j,mmp[i][j]='.'; else if(mmp[i][j] == 'E') ex=i,ey=j; else if (mmp[i][j] == 'K') { dkey[i][j] = nkey++; } } } bfs(); printf("%d\n", res); } return 0; }
hdu 4634 Swipe Bo(bfs 状态压缩)
最新推荐文章于 2016-09-09 18:11:11 发布