HDU1254:推箱子(bfs+dfs)

传送门

题意

给出一副图
0.空地1.墙2.箱子3.目的地4.人所在的位置
问最少几步能将箱子推到目的地

分析

这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,by)和人(mx,my)是否被访问过,用一个bfs求出最短路,另外dfs判断人是否能够到达推箱子的位置,写起来比较复杂,(弱鸡)

trick

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int t,n,m,mp[10][10],bx,by,mx,my,prex,prey,flag,ans;
int dir[4][2]={0,1,-1,0,0,-1,1,0};
int vis_p[10][10],vis[10][10][10][10];
struct node
{
    int bx,by;
    int mx,my;
    int step;
}tmp,p;
bool check(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]!=1) return 1;
        return 0;
}
void dfs(int prex,int prey,int mx,int my)
{
    if(prex==mx&&prey==my) { flag=1;return ; }
    if(flag) return ;
    for(int i=0;i<4;++i)
    {
        int x=prex+dir[i][0];
        int y=prey+dir[i][1];
        if(check(x,y)&&!vis_p[x][y])
        {
            vis_p[x][y]=1;
            dfs(x,y,mx,my);
        }
    }
}
void bfs2(int bx,int by,int mx,int my)
{
    memset(vis,0,sizeof(vis));
    ans=-1;
    queue<node>pq;
    while(!pq.empty()) pq.pop();
    tmp={bx,by,mx,my,0};
    pq.push(tmp);
    while(!pq.empty())
    {
        tmp=pq.front();pq.pop();
        if(mp[tmp.bx][tmp.by]==3) { ans=tmp.step;return ; }
        for(int i=0;i<4;++i)
        {
            p=tmp;
            p.bx+=dir[i][0],p.by+=dir[i][1];
            prex=tmp.bx-dir[i][0],prey=tmp.by-dir[i][1];
            if(!check(p.bx,p.by)) continue;
            if(!check(prex,prey)) continue;
            if(vis[p.bx][p.by][prex][prey]) continue;
            memset(vis_p,0,sizeof(vis_p));
            vis_p[tmp.bx][tmp.by]= vis_p[prex][prey]=1;
            flag=0;
            dfs(prex,prey,tmp. mx,tmp.my);
            if(!flag) continue;
            vis[p.bx][p.by][prex][prey]=1;
            p.mx=prex,p.my=prey;
            p.step++;
            pq.push(p);
        }
    }
}

int main()
{
    for(scanf("%d",&t);t--;)
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
        {
            scanf("%d",&mp[i][j]);
            if(mp[i][j]==4) { mx=i,my=j; }
            if(mp[i][j]==2) { bx=i,by=j; }
        }
        bfs2(bx,by,mx,my);
        printf("%d\n",ans);
    }
}
/*

6666
5 5
3 0 1 0 0
1 0 1 4 0
0 0 1 0 0
1 0 2 0 0
0 0 0 0 0
5 5
0 3 0 0 0
1 0 1 4 0
0 0 1 0 0
1 0 2 0 0
0 0 0 0 0
5 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 2 1 1
4 0 3 0 0
*/
posted @ 2017-04-10 16:46  遗风忘语  阅读(328)  评论(0编辑  收藏  举报