HDU 4771 Stealing Harry Potter's Precious

来源:互联网 发布:怪物猎人世界淘宝 编辑:程序博客网 时间:2024/06/05 07:31

题意:

给你一个迷宫,和几个宝藏点, 只有 ‘.’ 能走,‘@’是起点,求把所有宝藏都拿到的最小步数。 如果不能全部拿到,输出-1。

思路:

最开始以为深搜记录能过,但是后来才发现先到达宝藏的先后顺序也会影响步数,这是在工程听课,做的一道题,听学长讲的思路是:

分别以各个宝藏和起点为开始广搜到达各个地方的步数,记录下来, 由于宝藏个数数据量很小,所以只需要对经过的顺序进行一个全排列,然后求总和最小的一条路。

Code:

#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>#include<string>#include<queue>#include<stack>#include<bitset>#include<set>#include<map>#include<vector>#define LL long long#define See(a) cout << #a << " = " << a << endl;#define rep(i, s, e) for(int i = (s); i <= (e); ++i)#define drep(i, s, e) for(int i = (s); i >= (e); --i)#define debug(a, s, e) rep(_i, s, e) { cout << a[_i] << ' ';} cout << endl;#define debug2(a, s, e, ss, ee) { rep(i_, s, e) {debug(a[i_], ss, ee);}}using namespace std;const int N = 105;const int INF = 2e9;int n, m, t;char a[N][N];bool v[N][N];int f[10][10];int r[10][2];int mv[4][2] = {    1, 0,    0, 1,    -1, 0,    0, -1};struct Node{    int x, y, tep;    Node(int tep = 0):tep(tep){}    Node(int _x, int _y, int _tep):        x(_x), y(_y), tep(_tep){}}st, to;void bfs(int sx, int sy, int u){    queue<Node> Q;    st = Node(sx, sy, 0);    Q.push(st);    int x, y;    while(!Q.empty())    {        st = Q.front();Q.pop();        x = st.x;        y = st.y;        rep(i, 0, t)        {            if(x == r[i][0] && y == r[i][1])            {                f[u][i] = st.tep;//                printf("f[%d][%d] = %d\n", u, i, f[u][i]);            }        }        rep(i, 0, 3)        {            x = st.x + mv[i][0];            y = st.y + mv[i][1];            if(!v[x][y] && a[x][y] != '#' && a[x][y])            {                v[x][y] = true;                to = Node(x, y, st.tep + 1);                Q.push(to);            }        }    }}int main(){//    freopen("in.txt", "r", stdin);    while(~scanf("%d%d", &n, &m))    {        if(n == 0 && m == 0)        {            return 0;        }        memset(a, 0, sizeof(a));        memset(f, -1, sizeof(f));        rep(i, 0, 6)        {            f[i][i] = 0;        }        int sx, sy;        getchar();        rep(i, 1, n)        {            rep(k, 1, m)            {                scanf("%c", &a[i][k]);                if(a[i][k] == '@')                {                    sx = i;                    sy = k;                }            }            getchar();        }        scanf("%d", &t);        int x, y;        r[0][0] = sx;        r[0][1] = sy;        rep(i, 1, t)        {            scanf("%d%d", &r[i][0], &r[i][1]);//            a[r[i][0]][r[i][1]] = '^';        }//        debug2(a,  1, n, 1, m);        rep(i, 0, t)        {            memset(v, false, sizeof(v));            v[r[i][0]][r[i][1]] = true;            bfs(r[i][0], r[i][1], i);        }        int z[] = {1, 2, 3, 4, 5};        int ans = 2e9;//        debug2(f, 0, t, 0, t);        do{            int tem = f[0][z[0]];            int p = f[0][z[0]];            if(p < 0)            {                ans = -1;            }            rep(i, 1, t - 1)            {                p = f[z[i]][z[i - 1]];                if(p < 0)                {                    ans = -1;                }                tem += p;            }            if(tem < ans)            {                ans = tem;//                See(ans);//                debug(z, 0, t);            }        }while(next_permutation(z, z + t));//        See(f[4][0]);//        See(f[0][3]);//        See(f[3][2]);//        See(f[2][1]);//        See(f[4][0] + f[0][3] + f[3][2] + f[2][1]);        printf("%d\n", ans < 0 ? -1 : ans);    }    return 0;}
有的时候问题就是这么简单,分别对各个问题进行求解, 然后再进行有机的结合就是完整的答案。


0 0
原创粉丝点击