HDU 2012Find a way

版权声明: https://blog.csdn.net/qq_40829288/article/details/80626829

Find a way

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 22068    Accepted Submission(s): 7183


Problem Description
Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest. 
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
 

Input
The input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200). 
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’    express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
 

Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
 

Sample Input
 
  
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
 

Sample Output
 
  
66
88

66

题意:

Y和M分别从自己的位置出发,要在一个@的地方会合,其中#是墙不能走,. 是路可以走,每走一次耗费的11分钟,

求会合花费的最少时间。

题目思路:

定义一个以坐标为形参的bfs函数,然后记录下人物的初始坐标当初值,然后定义一个三维数组来分别存放两个人在每个点走的次数,这样的一个三维数组,不仅起到了标记位置的作用,还起到了记录所走次数的作用,最后,通过比较每个@位置的步数和,确定出所有@中最小的步数和,把这个和×11就是我们所求的时间;

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int inf=0x7fffffff,maxn=205;
char maze[maxn][maxn];
int vis[maxn][maxn][2];
int n,m,flag;
int go[4][2]={0,-1,-1,0,0,1,1,0};
struct node
{
	int x,y;
}A,B;
queue<node> Q;
//形参是坐标值;
void bfs(int x,int y)
{
	node current,next;

	current.x=x;

	current.y=y;

	vis[x][y][flag]=0;

	Q.push(current);
	while(!Q.empty())
	{
		current=Q.front();
		Q.pop();
		//在一个点的每一种可能走法通过for循环和go数组来确定
		for(int i=0;i<4;i++)
		{
			next.x=current.x+go[i][0];

			next.y=current.y+go[i][1];

			if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&maze[next.x][next.y]!='#'&&!vis[next.x][next.y][flag])
			{
				Q.push(next);

				//vis存放的值是其中一个人在到达每一个.和@位置时所用的时间

				vis[next.x][next.y][flag]=vis[current.x][current.y][flag]+1;
			}
		}
	}
}
int main()
{
	while(cin>>n>>m)
	{
		//在输入的时候就记下人物的位置;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			{
				cin>>maze[i][j];
				if(maze[i][j]=='Y')
					A.x=i,A.y=j;
				else if(maze[i][j]=='M')
					B.x=i,B.y=j;
			}
		memset(vis,0,sizeof(vis));
		//flag值就是为了对两个人到达@位置所用时间分别计数;
		flag=0;
		bfs(A.x,A.y);
		flag=1;
		bfs(B.x,B.y);
		int ans=inf;

		//通过两个for循环来找出在所有@位置两个人相遇时间的最小值。

		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			{
				if(maze[i][j]=='@'&&(vis[i][j][0]+vis[i][j][1]))
					ans=min(ans,vis[i][j][0]+vis[i][j][1]);
			}

		//输出的时候要*11,因为在路上花的时间是11分钟;

		cout<<ans*11<<endl;
	}
	return 0;
}


注意事项:

1.要对vis数组进行memset,不然个测试样例的结果都和数值最大的那个相同;
2.记录Y和X的位置的时候,别忘了分别对应的flag的值;

3.方向数组不能忘,标记数组不能忘,更不能忘memset;

4.结构体不能忘,队列头文件不能忘,数组函数的头文件不能忘;


猜你喜欢

转载自blog.csdn.net/qq_40829288/article/details/80626829