zoukankan      html  css  js  c++  java
  • hdu 1254 推箱子

    用BFS让箱子走一遍即可。

    其中判断箱子能否往前走,除了看它前面是否为墙,还要判断人能不能到它后面的方格。

    还有标记状态,箱子和人有一个位置不同,便是不同的状态。我用的哈希判重,其实开个四维数组也行,毕竟数据范围不大。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <map>
    
    #define Ri(a) scanf("%d", &a)
    #define Rl(a) scanf("%lld", &a)
    #define Rf(a) scanf("%lf", &a)
    #define Rs(a) scanf("%s", a)
    #define FOR(i,s,t) for(int i = (s) ; i <= (t) ; ++i )
    
    #define lchild o<<1
    #define rchild o<<1|1
    
    typedef long long ll;
    typedef unsigned long long ull;
    
    using namespace std;
    
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=10007;
    
    int dir[4][2]={0,-1,0,1,-1,0,1,0};
    
    int t,m,n,ans;
    int mp[10][10];
    
    struct node
    {
    	int bx,by,px,py;//箱子的坐标和人的坐标
    	int step;
    
    	inline int operator==(const node & a)
        {
            if( bx!=a.bx )return false;
            if( by!=a.by )return false;
            if( px!=a.px )return false;
            if( py!=a.py )return false;
            return true;
        }
        bool friend operator<(node a,node b)
        {
            return a.step>b.step;
        }
    };
    
    node start;
    vector <node> v[maxn];
    
    int myhash(node a){
    	return (a.bx * 11 + a.by*111 + a.px*1111 + a.py*11111 ) % maxn;
    }
    
    bool ok(int x,int y){
        if( x<0 || x>=m )return false;
        if( y<0 || y>=n )return false;
        if( mp[x][y]==1 )return false;
        return true;
    }
    
    bool visit(node a){
    	int ha = myhash(a);
    	int num = v[ha].size();
    	for(int i=0 ; i<num ; ++i){
    		if( v[ha][i] == a ){
    			//printf("has vised this state.
    ");
    			return true;
    		}
    	}
    	v[ha].push_back(a);
    	return false;
    }
    
    bool cango(node a,int sx,int sy){
    	//printf("box : %d,%d ; if can go to %d,%d 
    ",a.bx,a.by,sx,sy );
    
    	//bfs判断人能否到达mp[sx][sy]
    	node now=a,next;
    
    	bool vis[10][10];
    	memset(vis,0,sizeof vis);
    	vis[now.px][now.py]=1;
    	queue<node>q2;
    	q2.push(now);
    
    	while(!q2.empty()){
    		now=q2.front();
    		q2.pop();
    		//printf("now peo:: %d,%d
    ",now.px,now.py );
    		if(now.px==sx && now.py==sy){
    			return true;
    		}
    		for(int i=0;i<4;++i){
    			int nx = now.px+dir[i][0];
    			int ny = now.py+dir[i][1];
    
    			if( !ok(nx,ny) )continue;
    			if( vis[nx][ny])continue;
    			if( nx == now.bx && ny == now.by )continue;
    
    			vis[nx][ny]=1;
    
    			next.bx=now.bx;
    			next.by=now.by;
    			next.px=nx;
    			next.py=ny;
    			next.step=now.step+1;
    			//printf("    next peo:: %d,%d
    ",next.px,next.py );
    			q2.push(next);
    		}
    	}
    	return false;
    }
    
    int bfs(){
    	node now = start,next ;
        priority_queue <node> q;
    	q.push(now);
        visit(now);
    	while( !q.empty() ){
    		now=q.top();
    		q.pop();
    		//printf("now box:: %d,%d
    ",now.bx,now.by );
    		if( mp[now.bx][now.by]==3 ){
    			return now.step;
    		}
    		for(int i=0;i<4;++i){
    
    			int nx = now.bx + dir[i][0];
    			int ny = now.by + dir[i][1];
    			if( !ok(nx,ny) )continue;
    
    			int lx = now.bx - dir[i][0];
    			int ly = now.by - dir[i][1];
    			if( !ok(lx,ly) )continue;
    
    			if( cango(now,lx,ly) ){
    				next.bx=nx;
    				next.by=ny;
    				next.px=now.bx;
    				next.py=now.by;
    				next.step=now.step+1;
    
    				if( !visit(next) ) q.push(next);
    			}
    		}
    	}
    	return -1;
    }
    
    int main()
    {
    	//freopen("in.txt","r",stdin);
    	Ri(t);
    	while(t--){
    		for(int i=0;i<maxn;++i)v[i].clear();
    		Ri(m);Ri(n);
    		for(int i=0;i<m;++i){
    			for(int j=0;j<n;++j){
    				Ri( mp[i][j] );
    
    				if(mp[i][j]==2){
    					start.bx=i;
    					start.by=j;
    				}else if(mp[i][j]==4){
    					start.px=i;
    					start.py=j;
    					start.step=0;
    				}
    				//printf("%d ",mp[i][j] );
    			}
    			//printf("
    ");
    		}
    		ans=bfs();
    		printf("%d
    ",ans );
    	}
    	return 0;
    }
    
  • 相关阅读:
    php5使用docker工具安装mcrypt
    golang 三目运算的实现
    图片壁纸
    使用golang实现栈(stack)
    Qt 异常处理 QT_TRY和QT_CATCH
    OpenCV 实现图片HDR功能
    OpenCV HDR合成
    OpenCV .直方图均衡 CLAHE算法学习
    OpenCV 直方图均衡化原理
    OpenCV 直方图绘制以及直方图均衡化
  • 原文地址:https://www.cnblogs.com/bruce27/p/5036146.html
Copyright © 2011-2022 走看看