hdu 3309 广搜

题意:两个球,两个目标点,每次同时向 上下左右 移动这两个球,若前面是墙,则不动,两球不能重合,若一球到达目标点,另一球可从那里经过。。问最少多少步能将两球移动到目标点。

分析:广搜,用四维数组f[x][y][u][v]记录两球坐标分别为x y , u v 时的最少步数。注意两球要同时移动,且不能重合,但一球在目标点,另一球可以与它重合。

 

 

int dx[] = {-1,0,1,0};//up Right down Left
int dy[] = {0,1,0,-1};

const int M = 25;
const int N = 100005;
int n,m,ans;
char c[M][M];//地图
int x[N],y[N],u[N],v[N],p,q;//坐标数组
int xx,yy,uu,vv;
int f[M][M][M][M];//判重

void readdata(){
    memset(f,5,sizeof f);
    xx=yy=uu=vv=-1;
    cin>>n>>m;
    FOR(i,0,n) {
        cin>>c[i];
        FOR(j,0,m) if(c[i][j]=='B') {
            if(xx==-1) xx=i,yy=j;
            else uu=i,vv=j;
        }
    }
}

void bfs(){
    ans=-1; p=q=0;
    x[p]=xx; y[p]=yy; u[p]=uu; v[p]=vv; p++;
    f[xx][yy][uu][vv]=f[uu][vv][xx][yy]=0;

    while(p>q){
        int t = q++;
        FOR(i, 0, 4){
            xx=x[t]+dx[i]; yy=y[t]+dy[i]; uu=u[t]+dx[i]; vv=v[t]+dy[i];
            int x1=xx ,y1=yy, u1=uu, v1=vv;

           /* if(c[xx][yy] == '*' ) x1=x[t], y1=y[t];
            else if(xx==u[t]&&yy==v[t]){
                if(c[uu][vv]=='*'&&c[xx][yy]!='H') x1=x[t], y1=y[t];
            }else if(c[x[t]][y[t]]=='H') x1=x[t], y1=y[t];

            if(c[uu][vv]=='*') u1=u[t], v1=v[t];
            else if(uu==x[t]&&vv==y[t]){
                if(c[xx][yy]=='*'&&c[uu][vv]!='H') u1=u[t], v1=v[t];
            }else if(c[u[t]][v[t]]=='H'){
                if(u[t]!=x[t] || v[t]!=y[t]) u1=u[t], v1=v[t];
            }*/
            if(c[xx][yy] == '*' ) x1=x[t], y1=y[t];// ‘*'不能去
            else if(c[x[t]][y[t]]=='H') x1=x[t], y1=y[t];//已经在’H'上,不能移动

            if(c[uu][vv]=='*') u1=u[t], v1=v[t];
            else if(c[u[t]][v[t]]=='H'){
                if(u[t]!=x[t] || v[t]!=y[t]) u1=u[t], v1=v[t];//若两球在同一个‘H’上,则只移动第二个
            }

            if(x1==u1 && y1==v1 && c[x1][y1]!='H')continue;//两球重合

            if(f[x1][y1][u1][v1]>f[x[t]][y[t]][u[t]][v[t]]+1){
                if(c[x1][y1]=='H'&&c[u1][v1]=='H'&&(x1!=u1||y1!=v1)) {//找到解
                    ans=f[x[t]][y[t]][u[t]][v[t]]+1; return;
                }
                f[x1][y1][u1][v1]=f[x[t]][y[t]][u[t]][v[t]]+1;
                f[u1][v1][x1][y1]=f[x[t]][y[t]][u[t]][v[t]]+1;
                x[p]=x1; y[p]=y1; u[p]=u1; v[p]=v1; p++;
            }
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    #endif

    int T;
    cin>>T;
    while(T--){
        readdata();
        bfs();
        if(ans==-1) cout<<"Sorry , sir , my poor program fails to get an answer."<<endl;
        else cout<<ans<<endl;
    }

    return 0;
}

 

posted @ 2013-05-12 13:48  心向往之  阅读(131)  评论(0)    收藏  举报