网络赛 Saving Tang Monk(HDU 5025)

来源:互联网 发布:想学淘宝美工如何学 编辑:程序博客网 时间:2024/05/17 04:40

还是见的题太少了。

思路跟杭电1253基本一样的,就是多了一个权值会改变的点。

用个三维数组来记录每层走过的路径(这是一直卡我的地方,没写过这种姿势)。

这种思想相当于复制了几份原图,每一个编号的钥匙对应一层图, 这样就可以确保同一层不能走重复点,不同层可以走上一层走过的点。

在状态中保存一下已经杀死蛇的编号,防止同一路径中二次杀死同一条蛇。

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <stack>#include <cmath>#include <cstdlib>#include <vector>#include <map>#include <iostream>using namespace std;const int move[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};struct State{    int x, y, dist, key;    int snake[6];    State(int _x, int _y, int d, int k): x(_x), y(_y), dist(d), key(k){}    State(){}    bool operator < (const State &a)const    {        return dist > a.dist;//优先队列搜最小距离的点,保证最短路    }};struct Point//每条蛇的位置{    int x, y;    Point(int _x, int _y): x(_x), y(_y){}    Point(){}}snake[6];char mapp[110][110];int vis[110][110][11];priority_queue<State> que;int main(){    int n, m;    while(scanf("%d%d", &n, &m) && (n + m))    {        if(n + m == 0) break;         for(int i = 0; i < n; i++)            scanf("%s", mapp[i]);        int sx, sy, ex, ey;        int tt = 0;        for(int i = 0; i < n; i++)            for(int j = 0; j < n; j++)            {                if(mapp[i][j] == 'K')                    sx = i, sy = j;                else if(mapp[i][j] == 'T')                    ex = i, ey = j;                else if(mapp[i][j] == 'S')                {                    snake[tt].x = i;                    snake[tt].y = j;                    tt++;                }            }        while(!que.empty()) que.pop();           State tmp(sx, sy, 0, 0);        for(int i = 0; i < tt; i++)            tmp.snake[i] = 0;        memset(vis, 0, sizeof(vis));        que.push(tmp);        vis[sx][sy][0] = 1;        while(!que.empty())        {            tmp = que.top();            if(tmp.x == ex && tmp.y == ey && tmp.key == m)            {                printf("%d\n", tmp.dist);                break;            }               que.pop();            for(int i = 0; i < 4; i++)            {                int nx = tmp.x + move[i][0];                int ny = tmp.y + move[i][1];                if(                        nx >= 0 && ny >= 0          &&                         nx < n && ny < n            &&                         vis[nx][ny][tmp.key] == 0   &&                        mapp[nx][ny] != '#')                {                    State cur;                    for(int i = 0; i < tt; i++)                        cur.snake[i] = tmp.snake[i];                    cur.x = nx;                    cur.y = ny;                    cur.key = tmp.key;                    cur.dist = tmp.dist + 1;                    if(mapp[nx][ny] == 'S')                    {                        int i;                        for(i = 0; i < tt; ++i)                        {                            if(snake[i].x == nx && snake[i].y == ny)                                break;                        }                        if(cur.snake[i] == 0) //如果这条蛇没有在这条路径上,那么杀死它                        {                            cur.snake[i] = 1;                            cur.dist += 1;                        }                    }                    else if(mapp[nx][ny] <= '9' && mapp[nx][ny] >= '0')                    {                        if(mapp[nx][ny] -'0' == tmp.key + 1)//是需要的钥匙,取它                        {                            cur.key += 1;                        }                    }                    que.push(cur);                    vis[nx][ny][cur.key] = 1;//标记该钥匙对点的图走过                }            }        }        if(que.empty())        {            printf("impossible\n");         }    }    return 0;}




0 0
原创粉丝点击