南邮 OJ 1448 穿越机房

穿越机房

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 83            测试通过 : 15 

比赛描述

众所周知,在机房里想从一个地方到另一个地方很困难。因为机房里不仅有很多的 桌子,还摆了很多的椅子。现在,建冬哥想找嘉娃一起 apom,他不能在众目睽睽之下 对着嘉娃大吼,所以,他必须走到嘉娃跟前。

我们把机房分为宽度为 w,高度为 的 × 个格子。每个格子或者是一张桌子, 或者有一把椅子,或者什么都没有。建冬哥不能通过有桌子的格子,可以以一个单位时 间通过什么都没有的格子,但是通过有椅子的格子时,建冬哥需要花两个单位时间。

现在给出建冬哥和嘉娃的位置,以及机房的构造,你能知道建冬哥最快要多长时间 才能到嘉娃身边吗? 



输入

第一行 个整数 w,h,sr,sc,er,ec(3 ≤ w,h ≤ 20)。 和 表示机房的大小, (sr,sc)表示建冬哥处在第 sr 行第 sc 列,同理 (er, ec表示目前嘉娃的位置。开始时建冬哥和 嘉娃肯定在机房里。接下来是一个 × 的矩阵,代表机房的地形:

 '.': 表示该格子没有障碍物,通过需要 个单位时间。

'*': 表示该格子有一把椅子,通过需要 个单位时间。

'x': 表示该格子是一张桌子,不能通过。 

输出

一个整数,表示建冬哥到嘉娃所在位置的最短时间。之后加一个换行。 

样例输入

3 3 1 1 1 3 
.x*
*x.
*.*

样例输出

11

提示

最后的输出结果为建冬哥经过路径上所有点的时间之和。 


题目来源

第8届南京大学 ACM 程序设计大赛



#include<iostream>
#include<set>
using namespace std;

struct point{
	int dis,x,y;
};

bool operator<(point p1, point p2){
	if(p1.dis != p2.dis){
		return p1.dis < p2.dis;
	}else if(p1.x != p2.x){
		return p1.x < p2.x;
	}else{
		return p1.y < p2.y;
	}
}

int main(){
	int w,h,sr,sc,er,ec,i,j;
	char c;
	int cost[21][21];
	bool visited[21][21];
	set<point> pSet;
	set<point>::iterator it;
	scanf("%d%d%d%d%d%d",&w,&h,&sr,&sc,&er,&ec);
	for(i=1; i<=w; i++){
		while(getchar()!='\n');
		for(j=1; j<=h; j++){
			visited[i][j] = 0;
			scanf("%c",&c);
			if('.'==c){
				cost[i][j] = 1;
			}else if('*'==c){
				cost[i][j] = 2;
			}else if('x'==c){
				cost[i][j] = INT_MAX;
			}
		}
	}
	visited[sr][sc] = 1;
	point p1;
	p1.dis = cost[sr][sc];
	p1.x = sr;
	p1.y = sc;
	pSet.insert(p1);
	int x,y,d;
	while(!pSet.empty()){
		it = pSet.begin();
		d = it->dis;
		x = it->x;
		y = it->y;
		pSet.erase(it);
		if(x-1>=1 && !visited[x-1][y] && cost[x-1][y]!=INT_MAX){
			p1.dis = d+cost[x-1][y];
			p1.x = x-1;
			p1.y = y;
			if(p1.x == er && p1.y == ec){
				break;
			}
			visited[x-1][y] = 1;
			pSet.insert(p1);
		}
		if(x+1<=w && !visited[x+1][y] && cost[x+1][y]!=INT_MAX){
			p1.dis = d+cost[x+1][y];
			p1.x = x+1;
			p1.y = y;
			if(p1.x == er && p1.y == ec){
				break;
			}
			visited[x+1][y] = 1;
			pSet.insert(p1);
		}
		if(y-1>=1 && !visited[x][y-1] && cost[x][y-1]!=INT_MAX){
			p1.dis = d+cost[x][y-1];
			p1.x = x;
			p1.y = y-1;
			if(p1.x == er && p1.y == ec){
				break;
			}
			visited[x][y-1] = 1;
			pSet.insert(p1);
		}
		if(y+1<=h && !visited[x][y+1] && cost[x][y+1]!=INT_MAX){
			p1.dis = d+cost[x][y+1];
			p1.x = x;
			p1.y = y+1;
			if(p1.x == er && p1.y == ec){
				break;
			}
			visited[x][y+1] = 1;
			pSet.insert(p1);
		}
	}
	printf("%d\n",p1.dis);
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值