HDU 4771

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; 

}
View Code

 

你可能感兴趣的:(HDU)