poj 1376 Robot

#include<iostream>
#include<queue>
#include <cstdlib>
#include <stdio.h>
#include<string.h>
#define N 55
#define MAX 0x7fffffff
using namespace std;
typedef struct                                     
{ 
        int x,y;   
        int step;    //步数
        int dir;     //该Point的当前方向
}Point;
Point s,e;          //s:起点   e:终点
int map[N][N],vis[N][N];
int used[N][N][4];                      //之前从起点到当前点(x,y)的步数
int d[4][2]={0,1,1,0,0,-1,-1,0};                      //四个方向,右、下、左、上
int n,m;
bool ok(int x,int y,Point cur)            //判断(x,y)是否可以走
{
    return x>0&&x<n&&y>0&&y<m&&cur.step+1<used[x][y][cur.dir];   //如果(x,y)在坐标中,且当前走到该点的路径比之前的短则可走
}

int bfs()                                        //广搜
{
    Point cur,next;
    queue<Point> q;
    while(!q.empty()) q.pop();
    q.push(s);
    while (!q.empty())
    {
          cur=q.front();
          q.pop();
          if(cur.x==e.x&&cur.y==e.y)                     //如果当前节点为终点,结束
          return cur.step;
          if (cur.step+1<used[cur.x][cur.y][(cur.dir+1)%4])        //如果到了当前路径到了该点,向右转,其中used[][][]存的
                                                                   //实际上是上一次到达这点且也是面向当前右转,即两次状态一致,且这一次的路径更短
          {
              next=cur;
              next.step++;
              next.dir=(cur.dir+1)%4;
              q.push(next);
              used[cur.x][cur.y][(cur.dir+1)%4]=cur.step;
          }
          if(cur.step+1<used[cur.x][cur.y][(cur.dir+4-1)%4])         //与上面内容相似,但是是当前方向向左转
          {
              next=cur;
              next.step++;
              next.dir=(cur.dir+4-1)%4;
              q.push(next);
              used[cur.x][cur.y][(cur.dir+4-1)%4]=cur.step;      
          }
          for(int i=1;i<4;i++)                                      //当前位置(如果要转方向,则转弯方向后),向此时面对的方向前走1、2、3步
          {
                  int nx,ny;
                  nx=cur.x+i*d[cur.dir][0];
                  ny=cur.y+i*d[cur.dir][1];
                  if(map[nx][ny]==1)  break;
                  if (ok(nx,ny,cur))
                  {
                      next.x=nx;
                      next.y=ny;
                      next.step=cur.step+1;
                      next.dir=cur.dir;
                      q.push(next);                               //将当前点入队列
                      used[nx][ny][next.dir]=next.step;
                  }
          }
    }
    return -1;
}

int main(int argc, char** argv)
{
    char str[10];
    while (scanf("%d%d",&n,&m)!=EOF&&n!=0&&m!=0)
    {
          memset(map,0,sizeof(map));
          for (int i=0;i<n;i++)
          {
              for (int j=0;j<m;j++)
              {
                  int temp;
                  scanf("%d",&temp);                            //若该格子为黑,则将格子四个点的坐标赋值为1
                  if (temp==1)
                  {
                       map[i][j]=map[i][j+1]=map[i+1][j]=map[i+1][j+1]=1;      //将格子化为点的坐标来做。
                     
                  }   
                  used[i][j][0]=used[i][j][1]=used[i][j][2]=used[i][j][3]=MAX;     
              }
          }
          scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
          scanf("%s",str);
          if(strcmp(str,"east")==0)  s.dir=0;
          else if(strcmp(str,"south")==0)  s.dir=1;
          else if(strcmp(str,"west")==0)  s.dir=2  ;
          else s.dir=3;
          s.step=0;
          printf("%d\n",bfs());
    }
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值