洛谷P1189 SEARCH 题解 迭代加深

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

题目大意:
给你一个 \(n \times 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('\n');
    }
    return 0;
}
posted @ 2019-12-10 20:13  quanjun  阅读(262)  评论(0编辑  收藏  举报