poj 2049 Finding Nemo (反过来使用bfs)

poj 2049

题意:  Nemo被困在迷宫里, (其坐标为double型) , 迷宫的每个格子的任一面都有两个种可能:  门,墙; 在迷宫之外的为空地, 要求若Nemo的父亲能找到Nemo, 输出其经过最少的门, 否则输出-1;

解决方法:题目是父亲找Nemo, 可以当作Nemo如何经过最少的门走出迷宫, 每次仅移动一格, 所以可用bfs, 以Nemo所在方格为起点遍历迷宫, 每个方格用其左下角的坐标表示; 采用优先队列进行优化, 每次取出当前已经过门最少的位置.

code:

/***************
Problem from :
Problem describe :
data:
****************/

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<vector>
#include<string>
#define ll __int64
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 500;
int n, m, ans;
int xb[maxn][maxn], yb[maxn][maxn], dis[maxn][maxn];
struct node{
	int x;
	int y;
	int doors;
	bool operator < (const node &a) const {
		return doors>a.doors;
	}
};
bool judge(int sx, int sy){
	if(sx<0 || sy<0) return true;
        //该方格为空地, 故已经走出迷宫
        if(xb[sx][sy] == -1 || xb[sx][sy+1] ==-1 || yb[sx][sy]==-1 || yb[sx+1][sy]==-1) return true;
        else return false;
}
//以左下角坐标表示每一个小格 
int bfs(int sx, int sy)
{
	//cout << sx <<" "<<sy<<endl;
	if(judge(sx, sy)) return 0;
	memset(dis, inf, sizeof(dis));
	priority_queue<node>que;
	int i, cnt;
	node p;
	p.x = sx;
	p.y = sy;
	p.doors = 0;
	dis[sx][sy] = 0;
	que.push(p);
	while(!que.empty())
	{
		node q = que.top();
		que.pop();
		sx = q.x;
		sy = q.y;
		cnt = q.doors;
		//cout << sx << " " << sy <<endl;
		//向上走
		if(xb[sx][sy+1] == 0) {
			if(judge(sx, sy+1)) return cnt+1;
			p.x = sx;
			p.y = sy+1;
			p.doors = cnt+1;
			//确保从起点到达每个格子经过的门都是最少的 
			if(dis[p.x][p.y] > p.doors) dis[p.x][p.y] = p.doors, que.push(p);
		}
		//向下走 
		if(xb[sx][sy] == 0){
			if(judge(sx, sy-1)) return cnt+1;
			p.x = sx;
			p.y = sy-1;
			p.doors = cnt+1;
			if(dis[p.x][p.y] > p.doors) dis[p.x][p.y] = p.doors, que.push(p);
		}
		//向左走 
		if(yb[sx][sy] == 0){
			if(judge(sx-1, sy)) return cnt+1;
			p.x = sx-1;
			p.y = sy;
			p.doors = cnt+1;
			if(dis[p.x][p.y] > p.doors) dis[p.x][p.y] = p.doors, que.push(p);
		}
		//向右走 
		if(yb[sx+1][sy] == 0){
			if(judge(sx+1, sy)) return cnt+1;
			p.x = sx+1;
			p.y = sy;
			p.doors = cnt+1;
			if(dis[p.x][p.y] > p.doors) dis[p.x][p.y] = p.doors, que.push(p);
		}
	}
	return -1;
}
int main()
{
    //freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
	int x, y, r, l, i, j;
	while(scanf("%d %d", &n, &m), n!=-1 && m!=-1){
		memset(xb, -1, sizeof(xb));//-1表示此处非墙也非门, 即该方格为空地
		memset(yb, -1, sizeof(yb));
		for(i=1; i<= n; i++){
			scanf("%d %d %d %d", &x, &y, &r, &l);
			if(r==1){ //与y轴平行 
				for(j=y; j<l+y; j++) { //注意 这里要<号 而不是等于号 
					yb[x][j] = 1;
				}
			} else { //与x轴平行 
				for(j=x; j<l+x; j++) {
					xb[j][y] = 1;
				}
			}
		}
		for(i=1; i<=m; i++){
			scanf("%d %d %d", &x, &y, &r);
			if(r==1) {
				yb[x][y]=0;
			} else {
				xb[x][y]=0;
			}
		}
		double s_x, s_y;
		scanf("%lf %lf", &s_x, &s_y);
		//cout << s_x <<s_y<<endl;
		if(s_x > 199 || s_y>199 || s_x<1||s_y<1) printf("%d\n", 0);
		else printf("%d\n",bfs(int(s_x), int(s_y)));
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值