zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    NSURLSession的文件下载
    JSON解析(序列化和反序列化)
    NSURLSession的知识小记
    RunLoop的知识小记
    NSCach 的知识小记
    多图片下载综合案例-磁盘缓存处理
    模仿UIApplication创建单例
    LayoutSubviews的调用
    setValueForKeysWithDictionary的底层实现
    剑指offer 20:顺时针打印矩阵
  • 原文地址:https://www.cnblogs.com/quanjun/p/12018910.html
Copyright © 2011-2022 走看看