UVA 1600 Patrol Robert 巡逻机器人 (启发搜索BFS)

非常适合A*的一道题。

比普通的迷宫问题加一个信息k表示当前穿过的障碍物的数量。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAX = 21;

int m,n,k;

int C[MAX][MAX][MAX];
int G[MAX][MAX];

int tarx,tary;
struct node
{
   int g,h;
   int x,y;//对于本题 x+y 越大距离终点越近
   int k;
   bool operator < (const node& rhs) const{
      if(g + h > rhs.g + rhs.h) return true;
      if(g + h < rhs.h + rhs.g ) return false;
      if(g > rhs.g) return true;
      if(g < rhs.g) return false;
      return k > rhs.k;
   }
   void H(){
      h = tarx - x+ tary - y;
   }
};



node start;

#define C(n) C[n.x][n.y][n.k]
#define add(n) C(n) = true
int dx[] = { 0, 1, 0,-1};
int dy[] = { 1, 0,-1, 0};

int bfs()
{
   priority_queue<node> q;
   memset(C,false,sizeof(C));
   q.push(start); add(start);
   node cur,nxt;
   int i,nx,ny,nk;
   while(q.size()){
      cur = q.top();q.pop();
      if(cur.x == tarx && cur.y == tary) return cur.g;
      for(i = 0; i < 4; i++){
         nx = cur.x + dx[i];
         ny = cur.y + dy[i];
         if(nx >= m || nx < 0 || ny >= n || ny < 0 )continue;
         nk = G[nx][ny] ? cur.k+1 : 0;
         if(C[nx][ny][nk] || nk > k) continue;
         nxt.x = nx ; nxt.y = ny; nxt.g = cur.g+1 ; nxt.k = nk ; nxt.H();
         q.push(nxt); add(nxt);
      }
   }
   return -1;
}

int main()
{
  // freopen("in.txt","r",stdin);
   int T;
   int i,j;
   scanf("%d",&T);
   while(T--){
      scanf("%d%d%d",&m,&n,&k);
      for(i = 0;i < m; i++)
         for(j = 0;j < n; j++)
           scanf("%d",G[i]+j);
      tarx = m-1;tary = n-1;
      start.x = start.y = start.g = start.k = 0;
      //start.H();
      printf("%d\n",bfs());
   }
   return 0;
}

 

posted @ 2015-07-10 21:53  陈瑞宇  阅读(721)  评论(0编辑  收藏  举报