ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 A. Saving Tang Monk II(bfs)

 

题目链接:http://hihocoder.com/problemset/problem/1828

       题意是问有一个人从S点走到T点的最短路程,其中有氧气瓶分布在地图中,用'B'表示,它的作用是可以穿过'#'毒气室,每次穿过一个毒气室消耗一个氧气瓶,而氧气瓶最多能带5个,还有就是穿过毒气室需要额外花费1s的时间,地图中还存在加速药丸,用'P'表示,可以有无限个,每使用一次可以节省1s的时间。

       思路就是优先队列的bfs去跑,对于那些条件表示清楚就可以了。直接看代码吧,不难理解。


AC代码:

#include 
#define maxn 105
using namespace std;
struct Node{
	int x,y,num,step;
	Node (int x,int y,int num,int step) : x(x), y(y), num(num), step(step) {}
	bool operator < (const Node &a) const {
		if(a.step == step)return a.num < num;
		return a.step < step;
	}
};
int n,m,_Sx,_Sy,_Ex,_Ey;
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
bool vis[maxn][maxn][10];
char MAP[maxn][maxn];

bool Check(int x, int y){
	if(x >= 0 && y >= 0 && x < n && y < m){
		return true;
	}
	return false;
}

int bfs(){
	priority_queue q;
	memset(vis,0,sizeof(vis));
	vis[_Sx][_Sy][0] = 1;
	q.push(Node(_Sx, _Sy, 0, 0));
	while(!q.empty()){
		Node Now = q.top();
		q.pop();
		if(Now.x == _Ex && Now.y == _Ey){
			return Now.step;
		}
		for(int i=0;i<4;i++){
			int xx = Now.x + dir[i][0];
			int yy = Now.y + dir[i][1];
			int num = Now.num;
			int step = Now.step;
			if(Check(xx, yy)){
				if((MAP[xx][yy] == '.' || MAP[xx][yy] == 'S' || MAP[xx][yy] == 'T') && !vis[xx][yy][num]){
					vis[xx][yy][num] = 1;
					q.push(Node(xx, yy, num, Now.step + 1));
				}
				if(MAP[xx][yy] == 'B' && num < 5 && !vis[xx][yy][num + 1]){
					vis[xx][yy][num + 1] = 1;
					q.push(Node(xx, yy, num + 1, Now.step + 1));
				}
				if(MAP[xx][yy] == 'P' && !vis[xx][yy][num]){
					vis[xx][yy][num] = 1;
					q.push(Node(xx, yy, num, Now.step));
				}
				if(MAP[xx][yy] == '#' && num > 0 && !vis[xx][yy][num - 1]){
					vis[xx][yy][num - 1] = 1;
					q.push(Node(xx, yy, num - 1, Now.step + 2));
				}
			}
		}
	}
	return -1;
}

int main()
{
	while(~scanf("%d%d",&n,&m)){
		if(n == 0 && m == 0)break;
		for(int i=0;i

 

你可能感兴趣的:(ACM_搜索,补题补题补题)