zoukankan      html  css  js  c++  java
  • 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;    
    }
  • 相关阅读:
    运算符
    java--有关前台展示图片流的用法
    TortoiseSVN--Subversion客户端使用详解及问题解决
    SVN 文件的解锁方法
    JDBC中获取数据表的信息
    tomcat配置文件解决乱码问题
    正则表达式常用匹配
    Java:如何选择最为合适的Web开发框架
    键盘enter事件 兼容FF和IE和Opera
    PayPal 支付接口详解
  • 原文地址:https://www.cnblogs.com/staginner/p/2662304.html
Copyright © 2011-2022 走看看