zoukankan      html  css  js  c++  java
  • Keyboading 思路

    0x01 前置芝士

    还是先放个 link 吧。

    所需知识点:BFS。

    思维难度较高,实现简单。

    0x02

    题目大意:其实就是给你个图,按顺序走到相应的点,求所需最少步数(走到需要去的点会耗费一次步数)。特殊的,如果你要走的那个方向的字符和当前位一样,你会直接走的与当前位字符不一样的第一个点。

    这不难想到直接去初始化a。

    我们可以在一开始就暴力找出每个点的四个方向分别可以走到哪里。

    然后就是一个简单的BFS了。

    因为题意需要,我们可以再定义一个方向 (5),它表示当前点是否需要按下选择键。

    然后再在BFS的队列中多保存一个走到当前点时,是在前往所求数组中那一个位置上的点的路上。

    很显然每次前往某一个点时,重复走走过的点一定不划算,所以我们可以加个记忆数组 (vis)

    如果下一个点的 (vis) 小于当前这个点再走。(vis) 可以看做是第几次经过,或者说可以看做是在去哪个点的路上。(都能做。

    维护即可。

    0x03

    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int read() {
        int x = 0, k = 1;
        char s = getchar();
        while (s < '0' || s > '9') {
            if (s == '-')
                k = -1;
            s = getchar();
        }
        while (s >= '0' && s <= '9') {
            x = (x << 3) + (x << 1) + (s ^ 48);
            s = getchar();
        }
        return x * k;
    }
    
    const int MAXN = 55;
    const int MAXL = 1e4 + 5;
    int dx[4] = { 0, 1, 0, -1 };
    int dy[4] = { 1, 0, -1, 0 };
    char mp[MAXN][MAXN], s[MAXL];
    int r, c, len;
    
    struct node {
        int x, y;
        node() {}
        node(int X, int Y) {
            x = X;
            y = Y;
        }
    };
    node con[MAXN][MAXN][4];
    // con[i][j][k] 表示点 (i, j) 往 k 方向走会走到哪里。
    
    void init() { // 暴力初始化
        for (int i = 1; i <= r; i++)
            for (int j = 1; j <= c; j++)
                for (int k = 0; k < 4; k++) {
                    int x = i + dx[k], y = j + dy[k];
                    if (x < 1 || x > r)
                        continue;
                    if (y < 1 || y > c)
                        continue;
                    while (!(mp[i][j] ^ mp[x][y]) && x <= r && y <= c && x >= 1 && y >= 1)
                        x = x + dx[k], y = y + dy[k];
                    if (x >= 1 && x <= r && y >= 1 && y <= c)
                        con[i][j][k] = node(x, y);
                }
    }
    
    struct data {
        node now;
        int cnt, ans;
        data() {}
        data(node Now, int Cnt, int Ans) {
            now = Now;
            cnt = Cnt;
            ans = Ans;
        }
    };
    
    int vis[MAXN][MAXN];
    void bfs() {
        memset(vis, -1, sizeof vis);
        queue<data> q;
        q.push(data(node(1, 1), 0, 0));
        // cnt 表示这是在去那个位置上的点的路径上。
        // ans 表示最终答案
        while (!q.empty()) {
            data t = q.front();
            q.pop();
            int x = t.now.x, y = t.now.y;
            for (int i = 0; i <= 4; i++) {
                if (i == 4) {
                    if (mp[x][y] == s[t.cnt + 1] && vis[x][y] < t.cnt + 1) {
                        vis[x][y]++;
                        q.push(data(node(x, y), t.cnt + 1, t.ans + 1));
                        if (t.cnt + 1 == len) {
                            printf("%d
    ", t.ans + 1);
                            return;
                        }
                    }
                } else {
                    node nxt = con[x][y][i];
                    if (vis[nxt.x][nxt.y] < t.cnt && nxt.x && nxt.y) {
                        vis[nxt.x][nxt.y]++;
                        q.push(data(node(nxt.x, nxt.y), t.cnt, t.ans + 1));
                    }
                }
            }
        }
    }
    
    int main() {
        r = read(), c = read();
        for (int i = 1; i <= r; i++) scanf("%s", mp[i] + 1);
        init();
        scanf("%s", s + 1);
        len = strlen(s + 1);
        len++;
        s[len] = '*';
        bfs();
        return 0;
    }
    
  • 相关阅读:
    自定义事件 Event 、CustomEvent的使用
    移动端适配方案总结
    @media screen媒体查询实现页面自适应布局
    判断页面所有图片加载完成后执行操作
    JQ选择器篇2
    JQ 选择器篇1
    sql 日期转换字符大法
    SQL server从入门精通----3种分页
    SQL server从入门精通----触发器
    SQL server从入门精通---- 事务
  • 原文地址:https://www.cnblogs.com/Chain-Forward-Star/p/14052954.html
Copyright © 2011-2022 走看看