http://acm.hdu.edu.cn/showproblem.php?pid=4771
给一个地图,@是起点,给一些物品坐标,问取完所有物品的最小步数,不能取完输出-1
物品数最多只有四个,状态压缩一下bfs即可
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> using namespace std; int n, m, k; char G[105][105]; int vis[105][105][1<<4]; struct p { int x, y, key, step; }; int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, 1, -1}; p now; int bfs() { queue <p> q; now.step = 0; q.push(now); vis[now.x][now.y][0] = 1; while(!q.empty()) { p u = q.front(); q.pop(); for(int i = 0; i < 4; i++) { int xx = u.x + dx[i]; int yy = u.y + dy[i]; if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue; if(G[xx][yy] == '#') continue; p next; if(G[xx][yy] >= '0' && G[xx][yy] <= '3') { if(!vis[xx][yy][u.key]) { vis[xx][yy][u.key|(1<<(G[xx][yy]-'0'))] = 1; next.x = xx, next.y = yy, next.key = u.key|(1<<(G[xx][yy]-'0')), next.step = u.step + 1; if(next.key == (1<<k)-1) return next.step; q.push(next); } } else { if(!vis[xx][yy][u.key]) { vis[xx][yy][u.key] = 1; next.x = xx, next.y = yy, next.key = u.key, next.step = u.step + 1; q.push(next); } } } } return -1; } int main() { while(~scanf("%d%d", &n, &m)) { if(!n && !m) break; for(int i = 0; i < n; i++) scanf("%s", G[i]); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(G[i][j] == '@') now.x = i, now.y = j; scanf("%d", &k); int flag = 1; now.key = 0; memset(vis, 0, sizeof(vis)); for(int i = 0; i < k; i++) { int x, y; scanf("%d%d", &x, &y); if(G[x-1][y-1] == '#') flag = 0; else if(G[x-1][y-1] == '@') { G[x-1][y-1] = i + '0'; vis[x-1][y-1][1<<i] = 1; } else G[x-1][y-1] = i + '0'; } if(!flag) { puts("-1"); continue; } printf("%d\n", bfs()); } return 0; }