P1301 魔鬼之城

  一道bfs,只不过有一点小小的不同qwq…

  简单解释,移动的距离由你所在位置的数的大小决定,而且 (:3)......                     

  这道题介绍几个技巧:

    1.首先,对于bfs跑图经常用到的xx[],yy[],里面肯定不能放移动的距离,因为移动距离不固定。但是其实我们可以就写1,-1,这样只要在移动的时候用xx[i]*a[i][j],就是移动步数啦~(快夸我聪明);

    2.还有就是对于不能进行两次同样的跳跃,那么只要开一个三维数组就可以了;

  代码:

#include<cstdio>
#include<queue>
using namespace std;
int n,m;
bool ar;
int a[105][105];
bool vis[105][105][8];
int xx[]= {0,0,-1,1,1,1,-1,-1};
int yy[]= {1,-1,0,0,1,-1,1,-1};
struct xy
{
    int x,y,dis,dir;
};
queue <xy> Q;
void bfs()
{
    while(Q.size())
    {
        xy node=Q.front();
        Q.pop();
        for(int i=0; i<8; i++)
        {
            int nx=node.x+xx[i]*a[node.x][node.y];
            int ny=node.y+yy[i]*a[node.x][node.y];
            if(nx>0&&ny>0&&nx<=n&&ny<=m&&node.dir!=i&&!vis[nx][ny][i])
            {
                Q.push((xy)
                {
                    nx,ny,node.dis+1,i
                });
                vis[nx][ny][i]=1;
                if(nx==n&&ny==m)
                {
                    ar=1;
                    printf("%d",node.dis+1);
                    return ;
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            scanf("%d",&a[i][j]);
    Q.push((xy)
    {
        1,1,0,10
    });
    for(int i=0; i<8; i++)
        vis[1][1][i]=1;
    bfs();
    if(!ar)
    printf("NEVER");
    return 0;
}

 

posted @ 2018-11-27 18:54  paopo  阅读(198)  评论(0编辑  收藏  举报