hihoCoder 1092 : Have Lunch Together

题目大意:小hi和小ho去咖啡厅喝咖啡,咖啡厅可以看作是n * m的矩阵,每个点要么为空,要么被人、障碍物、椅子所占据,小hi和小ho想要找两个相邻的椅子。起初两个人都在同一个点,求两人到达满足要求的椅子所移动的最少步骤。

思路:先BFS找出每个S到达每个椅子的最短路径长度,然后遍历每一行和每一列找出最优解。

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<cstdlib>
#define INF 100000000
using namespace std;

int n,m,d[10010],dir[4][2] = {-1,0,1,0,0,-1,0,1};
bool vis[10010];
char ch[110][110];
queue<int>Q;

void bfs(int sx,int sy){
	int i,j,k;
	for(i=0;i<n;i++)
	    for(j=0;j<m;j++){
	    	k = i*m + j;
	    	vis[k] = false;
	    	d[k] = INF; 
	    }
	k = sx * m + sy ; 
	d[k] = 0;
	while(!Q.empty())
	    Q.pop();
	Q.push(k);
	while(!Q.empty()){
		int x = Q.front();
		int tx = x/m ;
		int ty = x%m ; 
		Q.pop();
		if(vis[x])
		    continue;
		vis[x] = true;
		for(i=0;i<4;i++){
			int ex = tx + dir[i][0];
			int ey = ty + dir[i][1];
			if(ex<0 || ex>=n || ey<0 || ey>=m || ch[ex][ey] == '#' || ch[ex][ey] == 'P')
			    continue;
			k = ex*m + ey;
			if(vis[k])
			    continue;
			if(ch[ex][ey] == 'S'){
				d[k] = d[k] < d[x] + 1 ? d[k] : d[x] + 1;
				continue;
			}
			d[k] = d[k] < d[x] + 1 ? d[k] : d[x] + 1;
			Q.push(k);
		}
	}
}

int main(){
	int i,j,p1,p2,ans,sx,sy;
	bool tag;
	while(scanf("%d%d",&n,&m) == 2){
		ans = INF;
		bool flag = false;
		for(i=0;i<n;i++)
			scanf("%s",ch[i]);
		for(i=0;i<n && !flag;i++)
		    for(j=0;j<m && !flag;j++)
		        if(ch[i][j] == 'H'){
		        	sx = i;
		        	sy = j;
		        	flag = true;
		        }
		        
		bfs(sx,sy);
		
		int t1,t2;
		for(i=0;i<n;i++){
			p1 = p2 = INF ;
			for(j=0;j<m;j++){
				if(ch[i][j] == 'S'){
					int temp = d[i*m+j];
					if(p1 == INF)
					    p1 = temp;
					else if(p2 == INF){
					    p2 = temp;
						ans = ans < p1 + p2 ? ans : p1 + p2 ;
						p1 = p2;
						p2 = INF ;
					}
				}
				else if(ch[i][j] == 'P' || ch[i][j] == '#' || ch[i][j] == '.'){
					p1 = INF ;
					p2 = INF ;
				}
			}
		}
		
		for(j=0;j<m;j++){
			p1 = p2 = INF ;
			for(i=0;i<n;i++){
				if(ch[i][j] == 'S'){
					int temp = d[i*m+j];
					if(p1 == INF)
					    p1 = temp;
					else if(p2 == INF){
					    p2 = temp;
						ans = ans < p1 + p2 ? ans : p1 + p2 ;
						p1 = p2;
						p2 = INF ;
					}
				}
				else if(ch[i][j] == 'P' || ch[i][j] == '#' || ch[i][j] == '.'){
					p1 = INF ;
					p2 = INF ;
				}
			}
		}
		if(ans < INF)
			printf("%d\n",ans);
		else
		    printf("Hi and Ho will not have lunch.\n");
	}
	return 0;
}
posted @ 2015-09-29 00:17  阿文的博客  阅读(284)  评论(0编辑  收藏  举报