非常适合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; }
时间: 2024-12-24 14:53:48