题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=839&page=show_problem&problem=4475
思路:用 BFS 求解。
注意:BFS 中的每一个结点应该为 (行,列,当前穿越障碍物的个数)。
代码:
/* Patrol Robot (UVa 1600) */ #include <iostream> #include <cstring> #include <queue> using namespace std; const int maxn = 22; struct Point{ int r, c, d, num; //行,列,当前距离,当前穿越障碍物的个数 Point(int r, int c, int d, int num = 0): r(r), c(c), d(d), num(num){} }; int vis[maxn][maxn][maxn]; // BFS 中每个节点为 ( 行,列,当前穿越障碍物的个数 ) int G[maxn][maxn]; int dc[] = {1,-1, 0, 0}; int dr[] = {0, 0, 1,-1}; int m, n, num; int BFS(); int main(){ //freopen("input.txt", "r", stdin); int T; cin >> T; while(T--){ memset(G, 0, sizeof(G)); cin >> m >> n >> num; for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) cin >> G[i][j]; cout << BFS() << endl; } } int BFS(){ queue<Point> q; q.push(Point(1, 1, 0)); memset(vis, 0, sizeof(vis)); vis[1][1][0] = 1; while(!q.empty()){ Point u = q.front(); q.pop(); if(u.r == m && u.c == n) return u.d; //cout << u.r << " " << u.c << endl; for(int i=0; i<4; i++){ Point v(u.r+dr[i], u.c+dc[i], u.d+1); if(v.r<1 || v.r>m || v.c<1 || v.c>n || vis[v.r][v.c][v.num]) continue; //排除越界和已访问的情况 if(G[v.r][v.c] == 1){ //判断是否需要穿越障碍物,若要,则记录下个数 v.num = u.num + 1; if(v.num > num) continue; //若大于了可穿越的障碍物的最大个数,排除 } q.push(v); //cout << v.r << " " << v.c << " " << v.num << endl; vis[v.r][v.c][v.num] = 1; } } return -1; }