题目
代码实现
/*
* POJ 3009: Curling 2.0
* 题意:m*n矩阵中,给出起点、终点、空格、障碍,从每个点可向4方前进,直到遇到障碍,打碎并停在障碍格的前面。求到达终点的最少前进次数。
* 类型:DFS+记忆化搜索
* 算法:从某点出发,向4个方向投掷,遇到障碍格,标记其为空格状态,继续递归障碍前一点,回退恢复障碍状态。每次递归直至到达终点或全部出界失败。
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int INF = 1000;
const int TYPE_VACANT = 0;
const int TYPE_BLOCK = 1;
const int TYPE_START = 2;
const int TYPE_GOAL = 3;
const int MAX_THROW = 10;
int m, n;
int mat[22][22];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int ans;
void dfs(int x, int y, int step) {
if(step >= MAX_THROW) {
return;
}
for(int i = 0; i < 4; ++i) { //从一个点的四个方向分别开始DFS
int xx = x;
int yy = y;
while(true) { //根据题意,击打一下后会朝着这个方向一直前进,直到碰到障碍物
xx += dx[i];
yy += dy[i];
if(xx < 0 || xx >= m || yy < 0 || yy >= n) { //如果出界
break;
}
if(mat[xx][yy] == TYPE_GOAL) { //如果到达目标点
ans = min(ans, step + 1); //判断是否是最小值
break;
}
if(mat[xx][yy] == TYPE_BLOCK) { //如果遇到障碍物
mat[xx][yy] = TYPE_VACANT; //则障碍物被击碎
int prex = xx - dx[i]; //冰壶回退到前一个点
int prey = yy - dy[i];
if(prex != x || prey != y) { //只要没有回到原点就从此点开始继续DFS
dfs(prex, prey, step + 1);
}
mat[xx][yy] = TYPE_BLOCK;
break;
}
}
}
}
void solve() {
ans = INF;
int sx, sy;
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
cin >> mat[i][j];
if(mat[i][j] == TYPE_START){
sx = i;
sy = j;
}
}
}
dfs(sx, sy, 0);
if(ans == INF){
ans = -1;
}
}
int main() {
while(cin >> n >> m && n > 0 && m > 0) {
solve();
cout << ans << endl;
}
return 0;
}
来源:CSDN
作者:KeepCodingKeepStudyi
链接:https://blog.csdn.net/hzl90572/article/details/88661676