zoukankan      html  css  js  c++  java
  • HDU1254 推箱子 DFS+BFS 算是不错的搜索题了

    有挺多小细节的,比如布尔条件的判断,还有状态的标志。

    /*
    *State: HDU1254     31MS    4920K    2558 B    C++
    *题目大意:
    *        推箱子,1代表墙,2代表箱子,3代表终点,4代表人。
    *解题思路:
    *        要先搜出人可以到达的位置,来判断箱子能否朝这个方向
    *        前进,之后还要注意一个状态的标志,一个位置可以走四次
    *        因为有四个不同的方向(这是此题的亮处吧)。
    *解题感想;
    *        贡献了好多个wa,就是因为没有想对状态。
    */
    View Code
    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    int const MAXN = 105;
    int Map[MAXN][MAXN];
    int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    int vst[MAXN][MAXN][4], n, m;
    
    struct node
    {
        int x, y, step;
        int px, py;
        node() {}
        node(int _x, int _y, int _px, int _py, int _s): x(_x), y(_y), px(_px), py(_py), step(_s) {}
    };
    
    void init()
    {
        memset(vst, 0, sizeof(vst));
        for(int i = 0; i < MAXN; i++)
            for(int j = 0; j < MAXN; j++)
                Map[i][j] = 1;
    }
    
    bool judge(int x, int y)
    {
        if(x >= 0 && x < n && y >= 0 && y < m 
            && Map[x][y] != 1)
            return true;
        else
            return false;
    }
    
    int pvst[MAXN][MAXN];
    void dfs(int x, int y, int a, int b)
    {
        pvst[x][y] = 1;
        int nx, ny;
        for(int i = 0; i < 4; i++)
        {
            nx = x + dir[i][0];
            ny = y + dir[i][1];
            if(nx == a && ny == b)
                continue;
            if(judge(nx, ny) && !pvst[nx][ny])
                dfs(nx, ny, a, b);
        }
    }
    
    int bfs(int sx, int sy, int x1, int y1)
    {
        queue<node> Q;
        node pre, cur;
    
        Q.push(node(sx, sy, x1, y1, 0));
    
        while(!Q.empty())
        {
            pre = Q.front();
            Q.pop();
    
            if(Map[pre.x][pre.y] == 3)
                return pre.step;
    
            for(int i = 0; i < 4; i++)
            {
                memset(pvst, 0, sizeof(pvst));
    
                dfs(pre.px, pre.py, pre.x, pre.y);
                int pa, pb;
                cur = pre;
                pa = pre.x + dir[(i + 2) % 4][0];
                pb = pre.y + dir[(i + 2) % 4][1];
    
                if(judge(pa, pb) && pvst[pa][pb] == 1)
                {
                    cur.x = pre.x + dir[i][0];
                    cur.y = pre.y + dir[i][1];
                    if(judge(cur.x, cur.y) && !vst[cur.x][cur.y][i])
                    {
                        cur.step = pre.step + 1;
                        cur.px = pre.x;
                        cur.py = pre.y;
                        Q.push(cur);
                        vst[cur.x][cur.y][i] = 1;
                    }
                }
            }
        }
        return -1;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int cas;
        scanf("%d", &cas);
        while(cas--)
        {
            init();
            scanf("%d %d", &n, &m);
            int sx, sy, px, py;
            for(int i = 0; i < n; i++)
                for(int j = 0; j < m; j++)
                {
                    scanf("%d", &Map[i][j]);
                    if(Map[i][j] == 2)
                        sx = i, sy = j;
                    if(Map[i][j] == 4)
                        px = i, py = j;
                }
            int sol = bfs(sx, sy, px, py);
            printf("%d\n", sol);
        }
        return 0;
    }
  • 相关阅读:
    第三次作业
    第二次作业
    10.30 非确定的自动机NFA确定化为DFA
    10.23 正规式、正规文法与自动机
    10.16 正规文法与正规式
    10.9 词法分析程序的设计与实现
    9.25 文法和语言总结与梳理
    9.18 语法树,短语,直接短语,句柄
    9.11 理解文法和语言
    9.4 了解编译原理
  • 原文地址:https://www.cnblogs.com/cchun/p/2656846.html
Copyright © 2011-2022 走看看