poj1376 搜索(BFS)

题目: http://poj.org/problem?id=1376

题意: 可以给机器人发两种指令:(1) GO: 一次朝一个方向移动1或2或3步  (2) TRUE: 转左或转右(一次只能转90度,不能连转两次) 。 每次执行1个指令都要花1秒。而且边界不能走。

思路: 用BFS,有三维数组保存状态,代表到达当前位置(x,y)在z方向上花的秒数(权重), 比较权重。比之前的状态权重小的,则覆盖当前状态。

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int  map[60][60];
int MinTime[60][60][4];//保存状态
int B1,B2,E1,E2;
char TRUE[10];
int direction[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
int M,N;
struct cnode
{
	int x;
	int y;
	int dir;//当前的方向
	int cost;//当前花的时间到达这里
};
int  bfs()
{
	int i;	
	queue<cnode> qu;
	cnode node;
	node.x = B1;
	node.y = B2;
	if(map[B1][B2] != 0 || map[E1][E2] !=0 )
	{
		return -1;
	}
	node.cost = 0;
	if(strcmp(TRUE,"east") == 0)
	{
		node.dir = 0;
	}
	else if(strcmp(TRUE,"south") == 0)
	{
		node.dir = 1;
	}
	else if(strcmp(TRUE, "west") == 0)
	{
		node.dir = 2;
	}
	else
	{
		node.dir = 3;
	}
	memset(MinTime, 127, sizeof(MinTime));
	qu.push(node);
	cnode current;
	MinTime[node.x][node.y][node.dir] = 0;
	while(!qu.empty())
	{
		current = qu.front();
	if(current.x == E1 &¤t.y == E2)
		{
			return current.cost;
		}
		cnode jump;
		qu.pop();
		//if(current.dir == 0)
		//{
			for(i = 1; i <= 3; i++)
			{
				jump = current;
	//			jump.y += i;
				jump.x += i * direction[current.dir][0];
				jump.y += i * direction[current.dir][1];
				jump.cost++;
				if(map[jump.x][jump.y] != 0)
				{
					break;
				}

				if(map[jump.x][jump.y] == 0 && MinTime[jump.x][jump.y][jump.dir] > jump.cost)
				{
					MinTime[jump.x][jump.y][jump.dir] = jump.cost;
					qu.push(jump);
				}
			}
/*			for(i = 1; i < 4; i++)
		{
			jump = current;
			jump.dir += i;
			jump.dir %= 4;
			int flag =  abs(jump.dir - current.dir);
			if(flag == 3)
			{
				jump.cost += 1;
			}
			else 
			{
				jump.cost += flag;
			}
			//if(map[jump.x][jump.y] == 0 && HasTrue[jump.x][jump.y] == false)
			if(map[jump.x][jump.y] == 0 && MinTime[jump.x][jump.y][jump.dir] > jump.cost)
			{
					MinTime[jump.x][jump.y][jump.dir] = jump.cost;

				qu.push(jump);
			}

		}*/

//		HasTrue[current.x][current.y] = true;
//下面是转方向的
			jump = current;
			jump.dir += 1;
			jump.dir %= 4;
			jump.cost++;
			if(map[jump.x][jump.y] == 0 &&  MinTime[jump.x][jump.y][jump.dir] > jump.cost)
			{
			MinTime[jump.x][jump.y][jump.dir] = jump.cost;

			qu.push(jump);
			}
			jump = current;
			jump.dir -= 1;
			jump.dir %= 4;
			if(jump.dir < 0)
			{
			jump.dir += 4;
			}
			jump.cost++;
			if(map[jump.x][jump.y] == 0 && MinTime[jump.x][jump.y][jump.dir] > jump.cost)
			{
			MinTime[jump.x][jump.y][jump.dir] = jump.cost;

			qu.push(jump);
			}
	}
	return -1;
}
int main()
{
//	freopen("poj1376.in", "r", stdin);
	//freopen("g.in", "r", stdin);
//freopen("poj1376.out","w",stdout);
	while(scanf("%d %d",&M,&N) != EOF)
	{
		if(M == 0 && N == 0)
		{
			break;
		}
		int  input[M + 10][N + 10];
		int i,j;
		for(i = 1; i <= M; i++)
		{
			for(j = 1; j <= N; j++)
			{
				scanf("%d",&input[i][j]);
			}
		}
		memset(map,255,sizeof(map));
		for(i = 1; i <= M + 1; i++)
		{
			for(j = 1; j <= N + 1; j++)
			{
				map[i][j] = 0;
			}
		}
		for(i = 1; i <= M; i++)
		{
			for(j = 1; j <= N; j++)
			{
				if(input[i][j] == 1)
				{
					map[i][j] = 1;
					map[i][j + 1] = 1;
					map[i + 1][j] = 1;
					map[i + 1] [j + 1] = 1;
				}
			}
		}
		for(i = 1; i <= M + 1; i++)
		{
			map[i][1] = - 1;
			map[i][N + 1] = -1;
		}
		for(i = 1; i <= N + 1; i++)
		{
			map[M + 1][i] = -1;	
			map[1][i] = -1;
		}
		scanf("%d %d  %d  %d",&B1,&B2,&E1,&E2);
		B1++;
		B2++;
		E1++;
		E2++;
		scanf("%s",TRUE);
		int ans;
		ans = bfs();
		printf("%d\n",ans);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值