1. 程式人生 > >P1301 魔鬼之城

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; }