POJ-1376-Robot

378 篇文章 0 订阅

     题目大意是给一个图,然后给你起点和终点,以及开始所处的方向,要求你求出从起点到终点的最小步数,如果无法到达则输出-1。这个题注意有4点:

1、它一秒可以执行2种命令,一种是向现在所面向的方向走1-3步,另外一种是向左或向右90度转向(不能向后转)。

2、图中为1的是障碍物,是不允许通过的,包括边界也不能允许,这一点需要注意下。

3、对搜索进行去重操作的时候需要记录所处位置的方向,因为这个题存在方向的问题,需要注意下,可以设置数组为vis[100][100][4],4代表4个方向。

4、对于题目所给处理,存在起点等于终点的情况,还有就是终点是无法到达的(比如终点为障碍物)需要特殊处理一下。

     这个题相当于是一个BFS搜索题吧,跟日常的搜索求最短步数一样,只是需要将题中所给的图进行一个转换,因为移动物体有直径的关系。

唉,最开始我们自己OJ上测试数据有误,导致一直过不了,结果一交POJ直接AC,无奈无力~

代码:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int x,y;
    int time;
    int pos;
};
int n,m,ex,ey,map[100][100];
bool vis[100][100][4];
int movex[4]={-1,0,1,0},movey[4]={0,1,0,-1};
int GetPos(char *str)
{
    if(!strcmp(str,"north"))
	return 0;
    if(!strcmp(str,"east"))
	return 1;
    if(!strcmp(str,"south"))
	return 2;
    return 3;
}
bool CanGo(int x,int y)
{
    if(x<1||x>=n||y<1||y>=m)
	    return false;
    if(map[x][y]||map[x+1][y]||map[x][y+1]||map[x+1][y+1])
	return false;
    return true;
}
int main()
{
    while(scanf("%d%d",&n,&m)&&(n||m))
    {
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
		scanf("%d",&map[i][j]);
	node ita;
	memset(vis,0,sizeof(vis));
	scanf("%d%d",&ita.x,&ita.y);
	scanf("%d%d",&ex,&ey);
	char op[20];
	scanf("%s",op);
	ita.pos=GetPos(op);
	ita.time=0;
	queue<node> a;
	a.push(ita);
	vis[ita.x][ita.y][ita.pos]=1;
	int ans=-1;
	if(ita.x==ex&&ita.y==ey)
	{
	    printf("0\n");
	    continue;
	}
	if(!CanGo(ex,ey))
	{
	    printf("-1\n");
	    continue;
	}
	while(!a.empty())
	{
	    node ita=a.front();
	    a.pop();
	    int itx=ita.x;
	    int ity=ita.y;
	    for(int i=1;i<=3;i++)
	    {
		itx+=movex[ita.pos];
		ity+=movey[ita.pos];
		if(!CanGo(itx,ity))
		    break;
		if(itx==ex&&ity==ey)
		{
		    ans=ita.time+1;
		    break;
		}
		if(!vis[itx][ity][ita.pos])
		{
		    node itb;
		    itb.x=itx;
		    itb.y=ity;
		    itb.time=ita.time+1;
		    itb.pos=ita.pos;
		    vis[itx][ity][itb.pos]=1;
		    a.push(itb);
		}
	    }
	    for(int i=0;i<4;i++)
	    {
		if(max(ita.pos,i)-min(ita.pos,i)==2)
		    continue;
		if(vis[ita.x][ita.y][i])
		    continue;
		node itb=ita;
		itb.time=ita.time+1;
		itb.pos=i;
		vis[itb.x][itb.y][itb.pos]=1;
		a.push(itb);
	    }
	    if(ans!=-1)
		break;
	}
	if(ans!=-1)
	    printf("%d\n",ans);
	else
	    printf("-1\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值