poj-3083-bfs+左转优先+右转优先

本文通过一个具体的迷宫寻路问题,介绍了如何使用不同的策略(左转优先、右转优先)来寻找从起点到终点的路径,并利用广度优先搜索(BFS)算法找到最短路径。文章详细展示了算法的具体实现过程。

题意:

给你一个图,有起点st,终点end,可走点'.',不可走点‘#’;

让你分别求出,左转优先,右转优先的路径长度,和最短路径。

做法:
左转优先和右转优先是模拟走的过程。

最短路用的bfs。

注意:

1,图的点(x,y)和其对应的位置转化。

2,,左转优先走的顺序是:左,前,右,后;

3,注意边缘情况,判断点是否可达。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct list
{
    int x;
    int y;
    int step;
}x;
int map[51][51];
int bian[2][4][2]={{{0,-1},{-1,0},{0,1},{1,0}},
                   {{0,1},{1,0},{0,-1},{-1,0}}};//左右转,方向,变化值,
int xxx[4]={0,1,0,-1};
int yyy[4]={-1,0,1,0};
int m,n;
int stx,sty,stleap;
int xx,yy,stt;
int search(int st,int end,int leap,int step)
{
   // printf("st=%d,end=%d,leap=%d,(%d,%d),stleap=%d\n",st,end,leap,stx,sty,stleap);
    int nowst;
    nowst=stx*m+sty;
    xx=stx;
    yy=sty;
    stt=stleap;
    step=1;
    while(nowst!=end)
    {
        if(map[xx+bian[leap][stt][0]][yy+bian[leap][stt][1]])
        {
        //    printf("1-----");
            xx=xx+bian[leap][stt][0];
            yy=yy+bian[leap][stt][1];
            if(leap==0)
            stt=((stt-1+4)%4);
            else
            stt=(stt+1)%4;
            nowst=(xx-1)*m+yy;
        }
        else if(map[xx+(stt-1)%2][yy+(2-stt)%2])
        {
           // printf("2-----");
            yy=yy+(2-stt)%2;
            xx=xx+(stt-1)%2;
            nowst=(xx-1)*m+yy;
        }
        else if(map[xx-bian[leap][stt][0]][yy-bian[leap][stt][1]])
        {
          //  printf("3-----");
            xx=xx-bian[leap][stt][0];
            yy=yy-bian[leap][stt][1];
            if(leap==0)
            stt=((stt+1+4)%4);
            else
            stt=(stt-1+4)%4;
            nowst=(xx-1)*m+yy;
        }
        else
        {
        //    printf("4-----");
            yy=yy-(2-stt)%2;
            xx=xx-(stt-1)%2;
            stt=(stt+2)%4;
            nowst=(xx-1)*m+yy;
        }
        step++;
     //   printf("step%d=%d,%d,stt=%d\n",step,xx,yy,stt);

      //  if(step>50)break;
    }
    return step;
}
int bfs(int st,int end)
{
   // printf("_________________bfs\n");
    int i;
    queue<struct list>q;
    int visit[101][101];
    memset(visit,0,sizeof(visit));
    struct list p;
    p.x=stx;
    p.y=sty;
    p.step=1;
    q.push(p);
    visit[stx][sty]=1;
    while(!q.empty())
    {
        x=q.front();
      //  printf("%d,%d\n",x.x,x.y);
        q.pop();
        if((x.x-1)*m+x.y==end)
        {
            return x.step;
        }
        for(i=0;i<4;i++)
        {
            if(x.x+xxx[i]>0&&x.y+yyy[i]>0&&x.x+xxx[i]<=n&&x.y+yyy[i]<=m&&!visit[x.x+xxx[i]][x.y+yyy[i]]&&map[x.x+xxx[i]][x.y+yyy[i]])
            {
                visit[x.x+xxx[i]][x.y+yyy[i]]=1;
                p.x=x.x+xxx[i];
                p.y=x.y+yyy[i];
                p.step=x.step+1;
                q.push(p);
         //       printf("push=(%d,%d)\n",p.x,p.y);
         //       if(p.step>20)return 0;
            }
        }
    }
    return 0;

}
int main()
{
  //  freopen("in.txt","r",stdin);
    int t,i,j;
    char str;
    scanf("%d%*c",&t);
    while(t--)
    {
        int st,end;
        scanf("%d %d%*c",&m,&n);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%c",&str);
                if(str=='#')map[i][j]=0;
                else if(str=='.')map[i][j]=1;
                else if(str=='S')
                {
                    map[i][j]=2,st=(i-1)*m+j;
                    stx=i;
                    sty=j;
                    if(j==1)stleap=1;
                    else if(i==1)stleap=2;
                    else if(i==n)stleap=0;
                    else if(j==n)stleap=3;
                }
                else if(str=='E')map[i][j]=3,end=(i-1)*m+j;
            }
            getchar();
        }
      //  printf("(%d,%d),%d,%d\n",stx,sty,st,end);
        int x,y,z;
        x=search(st,end,0,1);
        y=search(st,end,1,1);
        z=bfs(st,end);
        printf("%d %d %d\n",x,y,z);
    }
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值