杭電 1732 Push Box

經典的推箱子。。

寫的真好。。

開始還沒看明白,抄了一遍懂了。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
bool map[10][10][5];
int d[4][2]={-1,0,0,-1,1,0,0,1};
char maze[10][10],b[10][10];
int tx,ty,px,py;
struct point
{
	int x,y;
};
struct node
{
	point box[3];
	int px,py;
	int step;
	node()
	{
		memset(box,0,sizeof(box));
		px=py=0;
		step=0;
	}
	node & operator=(const node &t1)
	{
		memcpy(box,t1.box,sizeof(box));
		//memcpy(isover,t1.box,sizeof(isover));
		px=t1.px;
		py=t1.py;
		step=t1.step;
		return * this;
	}

}cur,tmp;
bool vis[8][8][8][8][8][8][8][8]; 
bool aim[9][8];
int n,m;
bool ok(node &e)
{
	for(int i=0;i<3;i++)
	{
		if(!aim[e.box[i].x][e.box[i].y])
			return 0;
	}
	return 1;
}
bool oor(int x,int y)
{
	if(x<0 || x>=n) return 0;
	if(y<0 || y>=m) return 0;
	return 1;
}


node start,en;
point hole[3];
queue<node>qu;



int bfs()
{
	memset(aim,0,sizeof(aim));
	memset(vis,0,sizeof(vis));

	for(int i=0;i<3;i++)
		aim[hole[i].x][hole[i].y]=1;


	start.step=0;
	while(!qu.empty()) qu.pop();
	//queue<node>qu;
	qu.push(start);
	//node cur,tmp;
	while(!qu.empty())
	{
		cur=qu.front();  qu.pop();
		if(ok(cur)) return cur.step;

		if(vis[cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y][cur.px][cur.py])
			continue;
		vis[cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y][cur.px][cur.py]=1;
		for(int i=0;i<4;i++)
		{
			int tx=cur.px+d[i][0];
			int ty=cur.py+d[i][1];
			if(!oor(tx,ty) || maze[tx][ty]=='#')
				continue;
			int j=0;
			for(;j<3;j++)
				if(cur.box[j].x==tx && cur.box[j].y==ty)
					break;
			//人要走的下一步沒有箱子
			if(j>=3)
			{
				tmp=cur;
				tmp.px=tx;
				tmp.py=ty;
				tmp.step++;
				qu.push(tmp);
			}
			else
			{//有箱子,tx,ty是箱子的座標
				tx+=d[i][0]; ty+=d[i][1];
				if(!oor(tx,ty) || maze[tx][ty]=='#')
					continue;
				int k=0;
				for(;k<3;k++)
					if(cur.box[k].x==tx && cur.box[k].y==ty)
						break;
				if(k>=3)
				{
					tmp=cur;
					tmp.box[j].x=cur.box[j].x+d[i][0];
					tmp.box[j].y=cur.box[j].y+d[i][1];
					tmp.px=cur.box[j].x, tmp.py=cur.box[j].y;
					tmp.step++;
					qu.push(tmp);
				}

			}
		}
	}
	return -1;
}
		
int main()
{
	int t;

	while(~scanf("%d %d",&n,&m))
	{
		int ind=0,ind2=0;
		//memset(ishole,0,sizeof(ishole));
		for(int i=0;i<n;i++)
		{
			scanf("%s",&maze[i]);
			for(int j=0;j<m;j++)
			{
				if(maze[i][j]=='*')//箱子座標
					start.box[ind].x=i,start.box[ind++].y=j;
				else if(maze[i][j]=='@')//目標座標
					hole[ind2].x=i,hole[ind2++].y=j;
				else if(maze[i][j]=='X')//人的座標
					start.px=i,start.py=j;
				if(maze[i][j]!='#')
					maze[i][j]='.';
			}
		}
		printf("%d\n",bfs());  
	}

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章