HDU2364(三维数组表示方向)

来源:互联网 发布:iapp源码大师官网 编辑:程序博客网 时间:2024/05/20 09:43

题意是:不能回头,但是必须转弯;
难点就在如何表示方向还有如何处理转弯;

要把方向看成图的一个属性,并不一定要按照模拟过程走一遍。

开始突发奇想从终点开始搜,结果把自己搞晕了,还是贴从起点(’@’)开始搜的代码吧。

/** * hdu2364 * 三维记忆bfs * 题目要求不能回头,但是可能转多个弯之后又回到走过的点,但还是有可能过去的,因为可能是从不同方向移动到这个点, * 所以,所以用一个三维的数组记录每一个点的状态,每个点有4种状态,即四个方向 * 要把方向看成图的属性 * ac */#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3fchar map[85][85];bool visit[85][85][5];int h, w;int startx,starty;struct node{    node(int _x = 0, int _y = 0, int _d = 0, int _cnt = 0):x(_x),y(_y),d(_d),cnt(_cnt){}    int x;    int y;    int d;    int cnt;//步数};node first;int bfs(){    queue<node> Q;    Q.push(first);    int next[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};    while(!Q.empty())    {        node temp = Q.front();        Q.pop();        if(temp.x == 1 || temp.x == h || temp.y == 1 || temp.y == w)        {            return temp.cnt;        }        for(int k = 0; k < 4; k++)        {            int nowx = temp.x + next[k][0];            int nowy = temp.y + next[k][1];            if(map[nowx][nowy] == '#' || visit[nowx][nowy][k])            {                continue;            }            if(nowx == startx && nowy == starty)            {                continue;            }            if(temp.d%2 == k%2)//k%2 == 0时上下,== 1时左右            {                //如果反向,啥也不做,相当于continue                if(temp.d == k)                {                    if(k%2==0 && map[temp.x][temp.y+1] == '#' && map[temp.x][temp.y-1] == '#')                    {                        visit[nowx][nowy][k] = 1;                        Q.push(node(nowx, nowy, k, temp.cnt+1));                    }                    if(k%2==1 && map[temp.x+1][temp.y] == '#' && map[temp.x-1][temp.y] == '#')                    {                        visit[nowx][nowy][k] = 1;                        Q.push(node(nowx, nowy, k, temp.cnt+1));                    }                }            }            else            {                visit[nowx][nowy][k] = 1;                Q.push(node(nowx, nowy, k, temp.cnt+1));            }        }    }    return -1;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(visit, 0, sizeof(visit));        memset(map, 0, sizeof(map));        scanf("%d%d", &h, &w);        for (int i = 1; i <= h; i++)        {            getchar();            for (int j = 1; j <= w; j++)            {                scanf("%c", &map[i][j]);                if (map[i][j] == '@')                {                    startx = i;                    starty = j;                }            }        }        first.x = startx; first.y = starty; first.d = -1; first.cnt = 0;        int result = bfs();        printf("%d\n", result);    }    return 0;}

还有优先队列版本:

/** * hdu2364 * 三维记忆bfs * 要把方向看成图的属性 * ac */#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3fchar map[85][85];bool visit[85][85][5];int h, w;int startx,starty;struct node{    node(int _x = 0, int _y = 0, int _d = 0, int _cnt = 0):x(_x),y(_y),d(_d),cnt(_cnt){}    int x;    int y;    int d;    int cnt;    friend bool operator < (const node &a,const node &b)    {        return a.cnt>b.cnt;    }};node first;int bfs(){    priority_queue<node> Q;    Q.push(first);    int next[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};    while(!Q.empty())    {        node temp = Q.top();        Q.pop();        if(temp.x == 1 || temp.x == h || temp.y == 1 || temp.y == w)        {            return temp.cnt;        }        for(int k = 0; k < 4; k++)        {            int nowx = temp.x + next[k][0];            int nowy = temp.y + next[k][1];            if(map[nowx][nowy] == '#' || visit[nowx][nowy][k])            {                continue;            }            if(nowx == startx && nowy == starty)            {                continue;            }            if(temp.d%2 == k%2)//k%2 == 0时上下,== 1时左右            {                //如果反向,啥也不做,相当于continue                if(temp.d == k)                {                    if(k%2==0 && map[temp.x][temp.y+1] == '#' && map[temp.x][temp.y-1] == '#')                    {                        visit[nowx][nowy][k] = 1;                        Q.push(node(nowx, nowy, k, temp.cnt+1));                    }                    if(k%2==1 && map[temp.x+1][temp.y] == '#' && map[temp.x-1][temp.y] == '#')                    {                        visit[nowx][nowy][k] = 1;                        Q.push(node(nowx, nowy, k, temp.cnt+1));                    }                }            }            else            {                visit[nowx][nowy][k] = 1;                Q.push(node(nowx, nowy, k, temp.cnt+1));            }        }    }    return -1;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(visit, 0, sizeof(visit));        memset(map, 0, sizeof(map));        scanf("%d%d", &h, &w);        for (int i = 1; i <= h; i++)        {            getchar();            for (int j = 1; j <= w; j++)            {                scanf("%c", &map[i][j]);                if (map[i][j] == '@')                {                    startx = i;                    starty = j;                }            }        }        first.x = startx; first.y = starty; first.d = -1; first.cnt = 0;        int result = bfs();        printf("%d\n", result);    }    return 0;}
原创粉丝点击