洛谷P1189 SEARCH 题解 迭代加深

题目链接:https://www.luogu.com.cn/problem/P1189

题目大意:
给你一个 (n imes m) 的矩阵,其中有一些格子可以走,一些各自不能走,然后有一个点是起点。
你走了 (q) 次,每次走的方向(上下左右四个方向)是知道的,但是不知道的是你每次走了多少格(至少 (1) 格),问最终你可能处在的位置。
(注意我这里开的变量名和原题描述的变量名不一样,不过不影响理解)

解题思路:
这道题目是其实是一道模拟题。
洛谷上面给的算法标签是“迭代加深”,但是其实这里只涉及“迭代”而没有“加深”。
迭代加深——以我的理解——应该是:

  • 先定一个小目标,搜索的深度不超过 (1) 层,看看能不能搜到答案;
  • 如果不行,再把搜索的最大深度设为 (2) ,看看能不能找到;
  • 如果不行,再把搜索的最大深度设为 (3) ,看看能不能找到;
  • ……
  • 直到设定目标为某一个深度 (D) ,并且此时我能够找到答案则退出。

但是其实我们这里没有接触到搜索,而只是将问题分解成了 (q) 步。

所以我可以开一个二维数组 (a[i][j]) 表示 ((i,j)) 这个格子可以作为第 (a[i][j]) 步的起点。

很显然,一开始我可以这么设:

  • 起点对应的 (a[i][j])(1)
  • 不能走的点对应的 (a[i][j])(-1)
  • 剩下的点(非起点的能走的点)对应的 (a[i][j])(0)

然后我们模拟每一步,我们从 (1)(q) 来枚举第 (id) 步,
假设当前在第 (id) 步,
我们再枚举每一个点 ((i,j)) ,如果 (a[i][j]) 恰好等于 (id) ,说明可以以 ((i,j)) 为起点向对应的方向走。
比如第 (id) 步的指令是“NORTH”,那么是往北走,
则我们可以循环将 (a[i-1][j],a[i-2][j], ...) 置为 (id+1),知道渠道不能走的点或者超出地图边界。

最后,我们可以通过判断 (a[i][j]) 来还原出这个地图:

  • 如果 (a[i][j]==id+1),则该点对应‘*’;
  • 如果 (a[i][j]==-1),则该点对应‘X’;
  • 其他情况下,该点对应‘.’。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
int n, m, q, a[maxn][maxn]; // n,m表示行和列,q表示方向的数量
char maze[maxn][maxn], ch[11];
bool in_map(int x, int y) { // 判断(x,y)是否在地图中
    return x>=0 && x<n && y>=0 && y<m;
}
void go_north(int x, int y, int id) {   // 往北走并标记
    while (in_map(x, y) && maze[x][y] != 'X') {
        a[x][y] = id+1;
        x --;
    }
}
void go_south(int x, int y, int id) {   // 往南走并标记
    while (in_map(x, y) && maze[x][y] != 'X') {
        a[x][y] = id+1;
        x ++;
    }
}
void go_west(int x, int y, int id) {   // 往西走并标记
    while (in_map(x, y) && maze[x][y] != 'X') {
        a[x][y] = id+1;
        y --;
    }
}
void go_east(int x, int y, int id) {   // 往东走并标记
    while (in_map(x, y) && maze[x][y] != 'X') {
        a[x][y] = id+1;
        y ++;
    }
}
void handle(int id, char ch[]) {    // 第id步判断是什么指令然后往相应的方向走
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            if (a[i][j] == id) {
                if (ch[0] == 'N') go_north(i-1, j, id);
                else if (ch[0] == 'S') go_south(i+1, j, id);
                else if (ch[0] == 'W') go_west(i, j-1, id);
                else go_east(i, j+1, id);
            }
        }
    }
}
int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i ++) cin >> maze[i];
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            if (maze[i][j] == 'X') a[i][j] = -1;
            else if (maze[i][j] == '*') a[i][j] = 1;
        }
    }
    cin >> q;
    for (int id = 1; id <= q; id ++) {
        cin >> ch;
        handle(id, ch);
    }
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            if (maze[i][j] == 'X') putchar('X');
            else if (a[i][j] == q+1) putchar('*');
            else putchar('.');
        }
        putchar('
');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/quanjun/p/12018910.html