HDU1254

来源:互联网 发布:php pdo exec execute 编辑:程序博客网 时间:2024/06/05 02:31

推箱子

/**************************************************************  作者:陈新  邮箱:cx2pirate@gmail.com  用途:hdu1254_2  时间ﺿ014.3.31 21:11  测试ﺿ04473642014-04-01 08:51:18Accepted125415MS296K3724 BG++超级旅行者   *************************************************************/ #include <cstdio>#include <memory.h>#include <queue>#include <map>using namespace std;#define MAPSIZE 7#define FLOOR 0#define WALL 1#define BOX 2#define DESTINATION 3#define WORKER 4//坐标typedef struct COOR{int x,y;bool operator ==(const COOR &rhs) const{return x == rhs.x && y == rhs.y;}bool operator !=(const COOR &rhs) const{return x != rhs.x || y != rhs.y;}bool operator <(const COOR &rhs) const{return x < rhs.x || (x == rhs.x && y < rhs.y);}}COOR;//worker,box的位置组成搜索节点//为使用map 对运算法重载typedef struct NODE{COOR worker;COOR box;int dir;int steps;bool operator <(const NODE &rhs)const{return worker < rhs.worker || (worker == rhs.worker && box < rhs.box);}}NODE;int gMap[MAPSIZE][MAPSIZE];//地图int vis[MAPSIZE][MAPSIZE];//dfs中使用,int mapX,mapY;//mapX地图高,mapY地图宽bool found;int DIREC[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};int REVER[4] = {1,0,3,2};//DIREC中反方向对应的索引queue<NODE> unvis;map<NODE,bool> visited;//用map记录已经扩展的节点,void initMap();//初始化地图int findAWay();//找到推箱子路径,有路径返回最小步骤,否则返回-1void getCoor(COOR *worker,COOR *box,COOR *dest);//从地图中获得worker,box,destination初始坐标COOR move(COOR from,int dir);//移动一个坐标,返回移动后的坐标void addNodes(COOR worker,COOR box,int steps);//把worker移动到box上下左右组成搜索节点,添加到unvisbool reach(COOR worker,COOR box,COOR aroundBox);//返回worker是否能到达box周围的坐标aroundBoxvoid dfs(COOR worker,COOR box,COOR aroundBox);//reach中采用的dfsbool notWall(COOR pos);//坐标在地图内且不是墙返回真,否则返回假int main(){int caseNum;scanf("%d",&caseNum);while(caseNum--){initMap();int steps = findAWay();printf("%d\n",steps);}}void initMap(){scanf("%d%d",&mapX,&mapY);for(int i = 0;i < mapX;i++){for(int j = 0;j < mapY;j++){scanf("%d",&gMap[i][j]);}}}int findAWay(){COOR worker,box,dest;getCoor(&worker,&box,&dest);visited.clear();while(!unvis.empty()){unvis.pop();}addNodes(worker,box,0);while(!unvis.empty()){NODE cur = unvis.front();unvis.pop();if(cur.box == dest){return cur.steps;}//printf("worker : %d %d\tbox : %d %d\tsteps : %d\n",cur.worker.x,cur.worker.y,cur.box.x,cur.box.y,cur.steps);COOR bNext = move(cur.box,cur.dir);if(notWall(bNext)){addNodes(cur.worker,bNext,cur.steps + 1);}}return -1;}void addNodes(COOR worker,COOR box,int steps){for(int dir = 0;dir < 4;dir++){COOR aroundBox = move(box,dir);if(reach(worker,box,aroundBox)){NODE node;node.worker = aroundBox;node.box = box;node.steps = steps;node.dir = REVER[dir];if(!visited[node]){visited[node] = true;unvis.push(node);}}}}COOR move(COOR from,int dir){COOR dest = from;dest.x += DIREC[dir][0];dest.y += DIREC[dir][1];return dest;}bool reach(COOR worker,COOR box,COOR aroundBox){memset(vis,false,sizeof(vis));found = false;dfs(worker,box,aroundBox);return found;}void dfs(COOR worker,COOR box,COOR aroundBox){if(worker == aroundBox){found = true;}if(found){return;}for(int dir = 0;dir < 4;dir++){COOR wNext = move(worker,dir);if(notWall(wNext) && wNext != box && !vis[wNext.x][wNext.y]){vis[wNext.x][wNext.y] = true;dfs(wNext,box,aroundBox);}}}bool notWall(COOR pos){return pos.x >= 0 && pos.x < mapX && pos.y >= 0 && pos.y < mapY && gMap[pos.x][pos.y] != WALL;}void getCoor(COOR *worker,COOR *box,COOR *dest){for(int i = 0;i < mapX;i++){for(int j = 0;j < mapY;j++){if(gMap[i][j] == WORKER){worker ->x = i;worker ->y = j;}else if(gMap[i][j] == BOX){box ->x = i;box ->y = j;}else if(gMap[i][j] == DESTINATION){dest ->x = i;dest ->y = j;}}}}


0 0
原创粉丝点击