Sicily 1135 飞越原野(BFS宽度优先搜索)

//BFS宽度优先搜索 //G[x][y][k]表示走到(x,y)后还能飞k步的最优值 #include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; const int MAX = 102; const int dir[4][2] = {1,0,-1,0,0,1,0,-1}; int N,M,D,ans; int G[MAX][MAX][MAX]; bool P[MAX][MAX],vis[MAX][MAX][MAX]; struct node { int x,y,d; }Q[MAX*MAX*MAX]; int hd,tl; void Push(int x,int y,int d) { Q[tl].x = x; Q[tl].y = y; Q[tl++].d = d; } void init()//初始化,一开始所有状态都不可达,记为MAX*MAX { hd = tl = 0; for(int i = 1;i <= N;++i) for(int j = 1;j <= M;++j) for(int k = 0;k <= D;++k) G[i][j][k] = MAX*MAX; G[1][1][D] = 0; } bool legal(int x,int y) { if(x < 1 || x > N || y < 1 || y > M || !P[x][y]) return false; return true; } void BFS() { int tx,ty,td,X,Y; init(); Push(1,1,D);//初始点进队 vis[1][1][D] = 1; while(hd < tl) { tx = Q[hd].x; ty = Q[hd].y; td = Q[hd++].d; for(int i = 0;i < 4;++i)//枚举4个方向 { for(int j = 1;j <= td;++j)//处理飞的情况 { X = tx + j*dir[i][0]; Y = ty + j*dir[i][1]; if(!legal(X,Y) || vis[X][Y][td-j]) continue; G[X][Y][td-j] = min(G[X][Y][td-j],G[tx][ty][td]+1); Push(X,Y,td-j); vis[X][Y][td-j] = 1; if(X == N && Y == M) return; } X = tx + dir[i][0];//走路的 Y = ty + dir[i][1]; if(!legal(X,Y) || vis[X][Y][td]) continue; G[X][Y][td] = min(G[X][Y][td],G[tx][ty][td]+1); Push(X,Y,td); vis[X][Y][td] = 1; if(X == N && Y == M) return; } } } int main() { //freopen("in.txt","r",stdin); char str[MAX]; scanf("%d%d%d",&N,&M,&D); for(int i = 1;i <= N;++i) { scanf("%s",str); for(int j = 0;j < M;++j) if(str[j] == 'P') P[i][j+1] = 1; } BFS(); ans = G[N][M][D]; for(int i = 0;i < D;++i) ans = min(ans,G[N][M][i]); if(ans != MAX*MAX) printf("%d/n",ans); else printf("impossible/n"); } 

你可能感兴趣的:(struct)