zoukankan      html  css  js  c++  java
  • 搜索入门练习题9 LETTERS 题解

    题目出处:《信息学奥赛一本通》第五章上机练习1 或者 POJ1154

    题目描述

    给出一个 (R imes S) 的大写字母矩阵,一开始你所处的位置在左上角,你可以向上下左右四个方向移动,并且不能移到曾经经过的字母(比如,你之前走到过一个'A'上,那么你以后就不能再走到'A'上了)。问最多可以经过几个字母。

    输入格式

    第一行,输入字母矩阵行数 (R) 和列数 (S)(1 le R,S le 20)
    接着输入 (R) 行,每行为一个包含 (S) 个字母的字符串。用于表示 (R imes S) 的字母矩阵。

    输出格式

    输出一个数字,用于表示最多能走过的不同的字母的个数。

    样例输入

    3 6
    HFDFFB
    AJHGDH
    DGAGEH
    

    样例输出

    6
    

    题目分析

    我们设行数为 (R) ,列数为 (S) ,用于保存字符的二维数组为 ch[][]
    我们开一个布尔数组 bool vis[26],其中 vis[0] 用于表示字母 'A' 是否走到过,vis[1] 用于表示字母 'B' 是否走到过,……, vis[25] 用于表示字母 'Z' 是否走到过。
    同时我们开一个搜索函数 dfs(int x, int y, int step) ,用于表示 “我当前在二维数组中的第 (x) 行第 (y) 列,并且我已经走了 (step) 步了” 这样一个状态。然后我遍历 ((x,y)) 的上下左右4个点 ((xx,yy)) ,如果 ((xx,yy)) 能走到并且 ch[xx][yy] 上的那个字符我之前没有走到过,那么我可以递归的执行 dfs(xx, yy, step+1)
    对于 step ,如果 step 比我当前记录的最大步数要大,则更新最大步数为 step(在下面的程序中我是用 ans 来表示最大步数的)。实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int R, S, ans;  // R,S分别表示行数和列数,ans表示最多经过字母数
    int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };   // dir数组用于表示上下左右4个方向
    char ch[22][22];    // ch数组用于表示我们的二位地图
    bool vis[26];   // vis数组用于记录26个字母是否有走过,其中'A'对应vis[0],'B'对应vis[1],…
    // in_map函数用于判断第x行第y列的元素是否超过地图边界
    bool in_map(int x, int y) {
        return x >= 0 && x < R && y >= 0 && y < S;
    }
    // dfs函数用于搜索,它表示当前在第x行第y列,已经走了step步
    void dfs(int x, int y, int step) {
        vis[ ch[x][y] - 'A' ] = true;   // 首先将当且(x,y)这个点对应的字母的vis值标记为true
        if (step > ans) ans = step;     // 如果step比ans大,更新ans为step
        for (int i = 0; i < 4; i ++) {  // 遍历四个方向
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];     // (xx,yy)就是新探索到的点
            if (in_map(xx, yy) && !vis[ ch[xx][yy] - 'A' ]) {   // 如果可以走,尝试性地走
                dfs(xx, yy, step+1);
            }
        }
        vis[ ch[x][y] - 'A' ] = false;  // 因为搜索是尝试放,所以推出本次搜索记得将vis值标记回false
    }
    int main() {
        cin >> R >> S;
        for (int i = 0; i < R; i ++) cin >> ch[i];
        dfs(0, 0, 1);
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    [daily][dpdk] 内核模块(网卡驱动)无法卸载
    [development][tcp/ip][ids] 一个简单有参考价值的库 libnids
    [development][http][libhtp] suricata的http库--libhtp
    [skill][http] http管道化连接
    [skill][telnet] 用telnet获取一个网页
    [daily][grub2] grub2修改内核选项
    [knowledge] big data things
    [knowledge][dpdk] open data plane
    [daily] docker
    [knowledge] 停止等待协议
  • 原文地址:https://www.cnblogs.com/zifeiynoip/p/11450727.html
Copyright © 2011-2022 走看看