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