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[][];
int vis[][][<<]; struct p {
int x, y, key, step;
}; int dx[] = {, -, , };
int dy[] = {, , , -}; p now; int bfs() {
queue <p> q;
now.step = ;
q.push(now);
vis[now.x][now.y][] = ;
while(!q.empty()) {
p u = q.front();
q.pop();
for(int i = ; i < ; i++) {
int xx = u.x + dx[i];
int yy = u.y + dy[i];
if(xx < || xx >= n || yy < || yy >= m) continue;
if(G[xx][yy] == '#') continue;
p next;
if(G[xx][yy] >= '' && G[xx][yy] <= '') {
if(!vis[xx][yy][u.key]) {
vis[xx][yy][u.key|(<<(G[xx][yy]-''))] = ;
next.x = xx, next.y = yy, next.key = u.key|(<<(G[xx][yy]-'')), next.step = u.step + ;
if(next.key == (<<k)-) return next.step;
q.push(next);
}
}
else {
if(!vis[xx][yy][u.key]) {
vis[xx][yy][u.key] = ;
next.x = xx, next.y = yy, next.key = u.key, next.step = u.step + ;
q.push(next);
}
}
}
}
return -;
} int main() {
while(~scanf("%d%d", &n, &m)) {
if(!n && !m) break;
for(int i = ; i < n; i++)
scanf("%s", G[i]);
for(int i = ; i < n; i++)
for(int j = ; j < m; j++)
if(G[i][j] == '@')
now.x = i, now.y = j;
scanf("%d", &k);
int flag = ;
now.key = ;
memset(vis, , sizeof(vis));
for(int i = ; i < k; i++) {
int x, y;
scanf("%d%d", &x, &y);
if(G[x-][y-] == '#') flag = ;
else if(G[x-][y-] == '@') {
G[x-][y-] = i + '';
vis[x-][y-][<<i] = ;
}
else G[x-][y-] = i + '';
}
if(!flag) {
puts("-1");
continue;
}
printf("%d\n", bfs());
}
return ;
}