//Memory 88K Time 63MS
#include <iostream>
#include <cstdio>
using namespace std;
//存储二维数组
int arr[21][21];
//最大行数 最大列数 起点行 起点列 结束行 结束列 最优解
int row, col, beginRow, beginCol, finishRow, finishCol, optimal;
//方向
int dire[4][4] = {{0, 1},
{0, -1},
{1, 0},
{-1, 0}};
//判断目前坐标是否越界
bool inMap(int reRow, int reCol) {
return reRow >= 0 && reRow < row && reCol >= 0 && reCol < col;
}
// 起点行 起点列 初始化步0
void dfs(int beginRow, int beginCol, int step) {
//当前步已经超过10 或者 当前步已经大于已经找到的最优解
if (step >= 10 || step >= optimal)
return;
//向4个方向遍历
for (int i = 0; i < 4; i++) {
//存储开始点的坐标,方便后续查看是否当前点为开始点旁的墙坐标
int nowRow = beginRow, nowCol = beginCol;
//初始化录入二维数组时,已经将所有的点的数都初始化为0或1
//如果当前点没有越界,并且不为墙
//则进一步查看是否当前点为结束点
while (inMap(nowRow, nowCol) && arr[nowRow][nowCol] == 0) {
if (nowRow == finishRow && nowCol == finishCol) {
step++;
optimal = min(optimal, step);
return;
}
//继续向目前遍历方向前进
nowRow += dire[i][0];
nowCol += dire[i][1];
}
//当前遍历方向,一直前进会越界,则舍弃当前方向,进行下一个方向的遍历
if (!inMap(nowRow, nowCol))
continue;
//若当前位置处于出发点旁的墙位置,说明这个方向不能前进,进行一个方向的遍历
if (nowRow == beginRow + dire[i][0] && nowCol == beginCol + dire[i][1])
continue;
//当前位置不是出发点旁的墙位置,则进行摧毁墙,并回退一个格子
if (arr[nowRow][nowCol] == 1) {
arr[nowRow][nowCol] = 0;
dfs(nowRow - dire[i][0], nowCol - dire[i][1], step + 1);
arr[nowRow][nowCol] = 1;
}
}
}
int main() {
while (scanf("%d%d", &col, &row), col, row) {
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
//初始化二维数组
scanf("%d", &arr[i][j]);
//记录出发点位置
if (arr[i][j] == 2) {
beginRow = i;
beginCol = j;
arr[i][j] = 0;
}
//记录结束点位置
if (arr[i][j] == 3) {
finishRow = i;
finishCol = j;
arr[i][j] = 0;
}
}
optimal = 1 << 10;
dfs(beginRow, beginCol, 0);
//若最优解没有更新,说明没有解打印-1
printf("%d\n", optimal != 1 << 10 ? optimal : -1);
}
return 0;
}
poj3009题解
最新推荐文章于 2022-04-11 09:26:15 发布