zoukankan      html  css  js  c++  java
  • UVA-10384 The Wall Pushers (IDA*)

    题目大意:走迷宫,遇到墙时可以推着墙走,但墙后还是墙时便不能推。求出一条任意的最短路径。

    题目分析:这道题出的比较人性,输入的时候便是将四周的墙用二进制数表示好了,其实这样减轻了做题人的负担。IDA*,当到最近的一个出口的距离加上当前层数cur都比maxd大时,则剪枝。不过,值得注意的是:当推着墙走的时候,涉及到3个格子周围的墙的变化(在边界除外)。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    struct XY
    {
        int x,y;
        XY(int _x,int _y):x(_x),y(_y){}
    };
    vector<XY>xy;
    int mp[4][6],sx,sy;
    int d[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
    int dd[4]={2,3,0,1};
    string pd="WNES",ans;
    
    void f()
    {
        xy.clear();
        for(int i=0;i<6;++i){
            if((mp[0][i]&2)==0)
                xy.push_back(XY(0,i));
            if((mp[3][i]&8)==0)
                xy.push_back(XY(3,i));
        }
        for(int i=0;i<4;++i){
            if((mp[i][0]&1)==0)
                xy.push_back(XY(i,0));
            if((mp[i][5]&4)==0)
                xy.push_back(XY(i,5));
        }
    }
    
    bool dfs(int cur,int maxd,int x,int y,string path)
    {
        if(cur==maxd){
            if(x==0&&((mp[x][y]&2)==0)){
                ans=path+'N';
                return true;
            }
            if(x==3&&((mp[x][y]&8)==0)){
                ans=path+'S';
                return true;
            }
            if(y==0&&((mp[x][y]&1)==0)){
                ans=path+'W';
                return true;
            }
            if(y==5&&((mp[x][y]&4)==0)){
                ans=path+'E';
                return true;
            }
            return false;
        }
    
        f();
        int minn=10000,l=xy.size();
        for(int i=0;i<l;++i)
            minn=min(minn,abs(x-xy[i].x)+abs(y-xy[i].y));
        if(cur+minn>maxd)
            return false;
    
        for(int i=0;i<4;++i){
            int nx=x+d[i][0],ny=y+d[i][1];
            if(nx<0||nx>3||ny<0||ny>5)
                continue;
            if(mp[x][y]&(1<<i)){
                if(mp[nx][ny]&(1<<i))
                    continue;
                mp[x][y]^=(1<<i);
                mp[nx][ny]^=(1<<dd[i]);
                mp[nx][ny]^=(1<<i);
                int nnx=nx+d[i][0],nny=ny+d[i][1];
                if(nnx>=0&&nnx<4&&nny>=0&&nny<6)
                    mp[nnx][nny]^=(1<<dd[i]);
                if(dfs(cur+1,maxd,nx,ny,path+pd[i]))
                    return true;
                mp[nx][ny]^=(1<<i);
                mp[nx][ny]^=(1<<dd[i]);
                mp[x][y]^=(1<<i);
                if(nnx>=0&&nnx<4&&nny>=0&&nny<6)
                    mp[nnx][nny]^=(1<<dd[i]);
            }else{
                if(dfs(cur+1,maxd,nx,ny,path+pd[i]))
                    return true;
            }
        }
        return false;
    }
    
    int main()
    {
        //freopen("UVA-10384 The Wall Pushers.txt","r",stdin);
        while(scanf("%d%d",&sy,&sx)&&(sx+sy))
        {
            --sx,--sy;
            for(int i=0;i<4;++i)
                for(int j=0;j<6;++j)
                    scanf("%d",&mp[i][j]);
            for(int maxd=0;;++maxd){
                if(dfs(0,maxd,sx,sy,"")){
                    cout<<ans<<endl;
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    多一盎司定律
    工作职场中,需要养成并实践的思维模型
    中国易经大师排名,易学十大泰斗人物
    大易人生 --- 曾老
    中道管理 --- 曾老
    大数据分析的道与术
    人应该服从自己的规划
    练习不是让你一次就把事情做好,而是帮助你做的越来越好
    让理想转个弯
    在酒桌上就能搞定生意
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4846495.html
Copyright © 2011-2022 走看看