HDU 1254 推箱子游戏(搞了一下午。。。)

中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254

一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断。

可以使用两个BFS,人这里也可以DFS。看见别人有用四维标记的有用图中图的判重,我也用一下图中图好了。



#include<iostream>     

#include<queue>

using namespace std;



int n, m;

int map[10][10];

int vec[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}};

int visited[10][10][4];//标记箱子。有四个方向,所有一个点可以推四次

int visitedP[10][10];//标记人



struct node

{

	int x;

	int y;

	int step;

	int innerMap[10][10];//保存每个点修改的图

	bool check()

	{

		if(x>=0 && x<n && y>=0 && y<m)

			return true;

		return false;

	}

}boxStart, peopleStart, peopleEnd, target;



int PeopleBFS(node t)

{

    peopleStart = t;

	memset(visitedP, 0, sizeof(visitedP));



	queue<node> Q;

	//找人的位置

	for (int i = 0; i<n; i++)

	{

		for (int j = 0; j<m; j++)

		{

			if (t.innerMap[i][j] == 4)

			{

				peopleStart.x = i;

				peopleStart.y = j;

				peopleStart.step = 0;

			}

		}

	}

	if(peopleStart.x == peopleEnd.x && peopleStart.y == peopleEnd.y)

		return true;

	visitedP[peopleStart.x][peopleStart.y] = true;



	Q.push(peopleStart);

	while (!Q.empty())

	{

		node q = Q.front();

		Q.pop();

		for (int i = 0; i<4; i++)

		{

			node p = q;

			p.x += vec[i][0];

			p.y += vec[i][1];

			p.step++;

			if (p.check() && !visitedP[p.x][p.y] && t.innerMap[p.x][p.y]!=1

                        && t.innerMap[p.x][p.y]!= 2)//不是墙不是箱

			{

				visitedP[p.x][p.y] = true;

				if (p.x == peopleEnd.x && p.y == peopleEnd.y)//可以到

				{

					return true;

				}

				Q.push(p);

			}

		}

	}

	return false;

}





int BoxBFS()

{

	queue<node> Q;

	Q.push(boxStart);

	while (!Q.empty())

	{

	    node q = Q.front();

		Q.pop();

		for (int i = 0; i<4; i++)

		{

			node p = q;

			p.x += vec[i][0];

			p.y += vec[i][1];

			p.step++;

			if (p.check() && !visited[p.x][p.y][i] && map[p.x][p.y] != 1)

			{

				//找出人站在箱子前进方向的反方向

				peopleEnd = q;

				peopleEnd.x = q.x - vec[i][0];

				peopleEnd.y = q.y - vec[i][1];

				if (peopleEnd.check())//人可以站在这个位置

				{

					if (PeopleBFS(peopleEnd))//人可以到达					{

						swap(p.innerMap[p.x][p.y], p.innerMap[q.x][q.y]);//箱子走一步

						swap(p.innerMap[peopleEnd.x][peopleEnd.y],

                     p.innerMap[peopleStart.x][peopleStart.y]);//人跟上					

                            visited[p.x][p.y][i] = true;

						if (map[p.x][p.y] == 3)//到达目的地

						{

							return p.step;

						}

					    Q.push(p);



					}

				}

			}

		}

	}

	return -1;

}





int main()

{

	int T;

	cin>>T;

	while (T--)

	{

		cin>>n>>m;

		memset(visited, 0, sizeof(visited));

		for (int i = 0; i<n; i++)

		{

			for (int j = 0; j<m; j++)

			{

				cin>>map[i][j];

				boxStart.innerMap[i][j] = map[i][j];

				if (map[i][j] == 2)//箱子起始

				{

					boxStart.x = i;

					boxStart.y = j;

					boxStart.step = 0;

				}

			}

		}

		cout<<BoxBFS()<<endl;

	}

	return 0;

}


你可能感兴趣的:(HDU)