• HDU 1813 Escape from Tetris


    HDU_1813

        一种可行的思路是迭代加深搜索,在搜索的过程中按字典序依次选择四种操作,然后将所有的空格统一执行这个移动操作,如果最终所有空格都移到了边缘,那么就说明找到了最优的深度同时也找到了字典序最优的操作序列。

        在搜索的时候可以加一个有效的剪枝:先bfs预处理出每个空格移到边缘所需的最少步数,这样如果在搜索过程中发现某个空格即便按最快的方案移动都不能在迭代加深限制的步数内到达边缘的话,就可以剪枝了。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #define MAXN 10
    #define MAXD 40
    #define INF 0x3f3f3f3f
    int dx[] = {0, -1, 1, 0}, dy[] = {1, 0, 0, -1};
    int N, M, g[MAXN][MAXN], ix[MAXD], iy[MAXD], dis[MAXN][MAXN];
    int list[1010];
    inline int inedge(int x, int y)
    {
        return x == 1 || x == N || y == 1 || y == N;    
    }
    int bfs(int sx, int sy)
    {
        int i, x, y, nx, ny, d[MAXN][MAXN];
        memset(d, -1, sizeof(d));
        std::queue <int> q;
        d[sx][sy] = 0, q.push(sx * 10 + sy);
        while(!q.empty())
        {
            x = q.front() / 10, y = q.front() % 10, q.pop();
            if(inedge(x, y)) return d[x][y];
            for(i = 0; i < 4; i ++)
            {
                nx = x + dx[i], ny = y + dy[i];
                if(g[nx][ny] && d[nx][ny] == -1)
                    d[nx][ny] = d[x][y] + 1, q.push(nx * 10 + ny);    
            }    
        }
        return 0;
    }
    void init()
    {
        int i, j;
        char b[MAXD];
        for(i = 1; i <= N; i ++)
        {
            scanf("%s", b + 1);
            for(j = 1; j <= N; j ++) g[i][j] = 1 - (b[j] - '0');    
        }
        M = 0;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= N; j ++)
            {
                if(g[i][j])
                {
                    if(inedge(i, j)) dis[i][j] = 0;
                    else
                    {
                        dis[i][j] = bfs(i, j);
                        ix[M] = i, iy[M] = j, ++ M;
                    }
                }
                else dis[i][j] = INF;
            }
    }
    int Max(int *x, int *y)
    {
        int i, ans = 0;
        for(i = 0; i < M; i ++) ans = std::max(ans, dis[x[i]][y[i]]);
        return ans;    
    }
    int dfs(int d, int *ix, int *iy)
    {
        if(Max(ix, iy) > d) return 0;
        if(d == 0) return 1;
        int i, j, x[MAXD], y[MAXD], nx, ny;
        for(i = 0; i < 4; i ++)
        {
            list[d] = i;
            for(j = 0; j < M; j ++)
            {
                nx = ix[j] + dx[i], ny = iy[j] + dy[i];
                if(inedge(ix[j], iy[j]) || g[nx][ny] == 0)
                    x[j] = ix[j], y[j] = iy[j];
                else
                    x[j] = nx, y[j] = ny;
            }
            if(dfs(d - 1, x, y)) return 1;
         }
         return 0;
    }
    void solve()
    {
        int i, dep;
        if(M == 0) return ;
        for(dep = 1; !dfs(dep, ix, iy); dep ++);
        for(i = dep; i > 0; i --)
        {
            if(list[i] == 0) puts("east");
            else if(list[i] == 1) puts("north");
            else if(list[i] == 2) puts("south");
            else puts("west");
        }
    }
    int main()
    {
        int t = 0;
        while(scanf("%d", &N) == 1)
        {
            init();
            if(t ++) printf("\n");
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?
    Groovy split竖杆注意
    使用Flask-Migrate进行管理数据库升级
    Fabric自动部署太方便了
    程序员的复仇:11行代码如何让Node.js社区鸡飞狗跳
    grails 私有库相关设置
    A successful Git branching model
    String to Date 多种格式转换
    C#搭建CEF(CEFGLUE) 环境。
    使用Win PE修改其他硬盘中的系统注册表
  • 原文地址:https://www.cnblogs.com/staginner/p/2662304.html
Copyright © 2020-2023  润新知