zoukankan      html  css  js  c++  java
  • #2102:A计划(DFS和BFS剪枝搜索)

    题意:

    有几个比较坑的地方总结一下, 很容易误解:

    1. 遇到#就必须走
    2. #不消耗时间
    3. #对面如果也是#也不能走, 要不然无限循环了
    4. 最短路径剪枝时, 发现不能走的#是要把两步都标注为-1并跳出

    题解:

    一道经典的DFS+剪枝的题目, 这道题数据量过百了(大致范围), 直接裸的DFS+回溯是过不去滴, 必须要剪枝
    可以看出, 当时间超过T不可达时直接跳出为可行性剪枝, 储存最短路径并只在当前小于最短路径才继续搜索为最优性剪枝

    BFS

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    int n, m, T;
    typedef struct Node {
        int x, y, z;
        int t;
    }Node;
    int A[2][15][15];
    int ans[2][15][15];	//存储状态
    int vis[2][15][15];	//是否走过
    int sx, sy, sz, ex, ey, ez;
    int arr[4][2] = { {0,-1},{0,1},{1,0},{-1,0} };	//四个方向
    queue<Node>q;
    bool check(int x, int y, int z) {
        if (x >= 0 && x < 2 && y >= 0 && y < n&&z >= 0 && z < m) {
            //不能是墙,时空机后面不能是时空机,且没有走过
            if (A[x][y][z] && !vis[x][y][z] && A[x][y][z] != 2)return 1;
            else return 0;
        }
        return 0;
    }
    void update_ans(Node &s) {
        //更新状态
        if (ans[s.x][s.y][s.z] < 0 || s.t < ans[s.x][s.y][s.z])ans[s.x][s.y][s.z] = s.t;
    }
    void BFS() {
        Node start;
        start.x = sx; start.y = sy; start.z = sz;
        start.t = 0;
        vis[sx][sy][sz] = 1;
        q.push(start);
        while (!q.empty()) {
            Node v = q.front(); q.pop();
            int i;
            update_ans(v);
            if (ans[ex][ey][ez] >= 0)return;
            for (i = 0; i < 4; i++) {
                Node t = v;
                t.y += arr[i][0]; t.z += arr[i][1];
                t.t++;
                if (A[t.x][t.y][t.z] == 2) { t.x = (t.x + 1) % 2; }
                if (check(t.x, t.y, t.z)) {
                    vis[t.x][t.y][t.z] = 1;
                    q.push(t);
                }
            }
        }
    }
    int main() {
        int C;
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
        scanf("%d", &C);
        while (C--) {
            scanf("%d%d%d", &n, &m, &T);
            int i, j, k;
            while (!q.empty())q.pop();
            memset(A, 0, sizeof(A));
            for (i = 0; i < 2; i++) {
                for (j = 0; j < n; j++) {
                    for (k = 0; k < m; k++) {
                        char ch;
                        scanf("%c", &ch);
                        while (ch == '
    ' || ch == ' ' || ch == '' || ch == '?')scanf("%c", &ch);
                        if (ch == 'S') {
                            A[i][j][k] = 1; sx = i;
                            sy = j; sz = k;
                        }
                        else if (ch == 'P') {
                            A[i][j][k] = 9; ex = i;
                            ey = j; ez = k;
                        }
                        else if (ch == '*')A[i][j][k] = 0;
                        else if (ch == '#')A[i][j][k] = 2;
                        else if (ch == '.')A[i][j][k] = 1;
                    }
                }
            }
            memset(ans, -1, sizeof(ans));
            memset(vis, 0, sizeof(vis));
            BFS();
            if (ans[ex][ey][ez] >= 0 && ans[ex][ey][ez] <= T)printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    

    DFS

    #include<iostream>
    #include<string.h>
    #define ms(a,b) memset(a,b,sizeof(a))
    using namespace std;
    int n, m, times, flag;
    int dx[] = { 0,-1,0,1 };
    int dy[] = { -1,0,1,0 };
    bool book[2][11][11];
    char map[2][11][11];
    bool check(int x, int y) {
        if (x >= 0 && x < n && y >= 0 && y < m)return 1;
        else return 0;
    }
    bool dfs(int x, int y, int z, int t) {
        if (map[z][x][y] == 'P') {
            if (t <= times)return 1;
            else return 0;
        }
        for (int i = 0; i < 4; ++i) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (check(nx, ny)) {
                if (!book[1 - z][nx][ny] && map[z][nx][ny] == '#'&&map[1 - z][nx][ny] != '*'&&map[1 - z][nx][ny] != '#')
                {
                    book[1 - z][nx][ny] = 1;
                    if (dfs(nx, ny, 1 - z, t + 1))
                        return 1;
                    book[1 - z][nx][ny] = 0;
                }
                else
                    if (!book[z][nx][ny] && map[z][nx][ny] != '#'&&map[z][nx][ny] != '*')
                    {
                        book[z][nx][ny] = 1;
                        if (dfs(nx, ny, z, t + 1))
                            return 1;
                        book[z][nx][ny] = 0;
                    }
            }
            
    
        }
        return 0;
    }
    int main() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n >> m >> times;
            ms(book, 0);
            ms(map, 0);
            for (int i = 0; i < 2; i++){
                getchar();
                for (int j = 0; j < n; j++){
                    for (int k = 0; k < m; k++)
                        cin >> map[i][j][k];
                    getchar();
                }
            }
            book[0][0][0] = 1;
            if (dfs(0, 0, 0, 0))cout << "YES" << endl;
            else cout << "NO" << endl;
            
        }
    }   
    
  • 相关阅读:
    远程访问linux环境安装图形界面问题解决汇总
    如何通过SecureCRT FTP上传下载文件
    X-Frame-Options 响应头
    Openresty 学习笔记(四)lualocks包管理器安装使用
    PHP7 学习笔记(十六)Yaconf 一个高性能的配置管理扩展
    网络工具(一)frp 供内网穿透服务的工具
    博客园自定义样式参考
    Redis学习笔记(二)解析dump.rdb文件工具之redis-rdb-tools
    Docker 从入门到放弃(四)Docker+Jenkins_自动化持续集成
    PHP7 学习笔记(十五)Repository 模式实现业务逻辑和数据访问的分离
  • 原文地址:https://www.cnblogs.com/RioTian/p/12819500.html
Copyright © 2011-2022 走看看