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;
    }
    
  • 相关阅读:
    VScode 修改中文字体
    missing KW_END at ')' near '<EOF>'
    SQL inner join, join, left join, right join, full outer join
    SQL字符替换函数translater, replace
    SQL COOKBOOK SQL经典实例代码 笔记第一章代码
    sqlcook sql经典实例 emp dept 创建语句
    dateutil 2.5.0 is the minimum required version python
    安装postgresql后找不到服务 postgresql service
    Postgres psql: 致命错误: 角色 "postgres" 不存在
    【西北师大-2108Java】第十六次作业成绩汇总
  • 原文地址:https://www.cnblogs.com/bruce27/p/5036146.html
Copyright © 2011-2022 走看看