题目链接:
题意: 一块N X M 的墙壁,求从S点出发 到T点的最短时间 每次只能爬一步,且只能左右脚交替爬行,墙上每个方块中的数字标明方块的"光滑 等级",标有数字t 的方块将花费他t 个单位时间安全地将他的脚踏在上面。 题解: 队列结构体中有4个变量(x,y,步数,固定的脚(0左脚,1右脚))。将所有s点的左脚开始和右脚开始 加入队列 标记数组要有三维 表示用哪只脚访问了这个坐标(x,y) 然后加入优先队列优化 按BFS搜索 第一个到达T的即是答案 代码:#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct node { int x,y,step,flag; friend bool operator<(const node a,node b) //优先队列 时间少优先 { return a.step>b.step; } } head; char map[105][105]; int vis[2][105][105]; //三维 int fx[2][9][2]= {{0,1, 0,2, 0,3, 1,1, 1,2, 2,1, -1,1, -1,2, -2,1},{0,-1, 0,-2, 0,-3, 1,-1, 1,-2, 2,-1, -1,-1, -1,-2, -2,-1}}; //左脚和右脚的9个方向 int m,n,ans; void bfs() { priority_queue<node>q; int i,j,tx,ty; for(i=1; i<=m; i++) for(j=1; j<=n; j++) { cin>>map[i][j]; if(map[i][j]=='S') { q.push((node){i,j,0,0}); q.push((node){i,j,0,1}); //左脚右脚开始 都要加入 vis[0][i][j]=vis[1][i][j]=1; } } while(!q.empty()) { head=q.top(); q.pop(); for(i=0; i<9; i++) { tx=head.x+fx[head.flag][i][0]; ty=head.y+fx[head.flag][i][1]; if(tx<1||ty<1||tx>m||ty>n||vis[1-head.flag][tx][ty]||map[tx][ty]=='X') //当前是head.flag表示的脚 则下一步是1-head.flag表示的脚 continue; vis[1-head.flag][tx][ty]=1; if(map[tx][ty]=='T') { ans=head.step; return; } q.push((node){tx,ty,head.step+map[tx][ty]-'0',1-head.flag}); } } return; } int main() { while(scanf("%d%d",&n,&m)&&m) { ans=-1; memset(vis,0,sizeof(vis)); bfs(); cout<<ans<<endl; } return 0; }
zoj 3103 Cliff Climbing 优先队列+BFS
原文:http://blog.csdn.net/axuan_k/article/details/43494197