广搜,用到优先队列,跟hdu1026差不多。但须注意几个问题:
1、可以往回走,由于可以重设时间,有时需要拐弯去“加油”,但可重设时间的结点不能在让它有机会被重走,不然就进入死循环了。
2、队列每次弹出的都是用时最少的,需要自定义排序
#include <iostream> #include <queue> using namespace std; int map[9][9]; int n,m; int dir[4][2]={0,1, 1,0, -1,0, 0,-1}; struct Node{ int x,y; int time; int step;//剩余的步数 bool operator<(const Node &a) const{ return a.time<time; } }; int bfs(int x, int y, int end_x, int end_y) { priority_queue<Node>que; struct Node start; start.x=x; start.y=y; start.time=0; start.step=6; que.push(start); while(!que.empty()) { struct Node cur=que.top(); que.pop(); if(cur.step==0) continue;//时间到了,结束搜索 if(cur.step>=1 && cur.x==end_x && cur.y==end_y) return cur.time;//注意要保证剩余时间大于1 for(int i=0; i<4; i++){ int xtmp=cur.x+dir[i][0]; int ytmp=cur.y+dir[i][1]; if(map[xtmp][ytmp]==0 || xtmp<0 || xtmp>=n || ytmp<0 ||ytmp>=m) continue; struct Node next; next.x=xtmp; next.y=ytmp; next.time=cur.time+1; next.step=cur.step-1; if(map[xtmp][ytmp]==4 && next.step>=1){//注意重设时间的条件 next.step=6; map[xtmp][ytmp]=0; } que.push(next); } } return -1; } int main() { int t, i,j, start_x, start_y, end_x, end_y; cin>>t; while(t--) { scanf("%d%d", &n, &m); for(i=0; i<n; i++){ for(j=0; j<m; j++){ scanf("%d", &map[i][j]); if(map[i][j]==2){ start_x=i; start_y=j; } else if(map[i][j]==3){ end_x=i; end_y=j; } } } int result=bfs(start_x, start_y, end_x, end_y); cout<<result<<endl; } return 0; }
一直都是无题解不AC,这次由于做完hdu 1026没多久,很快想到解决的办法,但是在细节处理上还是用了很长的时间。加油!
时间: 2024-10-10 23:08:28