盲人摸象 (bfs+dfs) 2020 jsk蓝桥杯省赛第二次模拟赛

思路:
1:对于正常人,限制条件较少,我们可以直接采用bfs获得最短路径;
2:对于左手盲人或右手盲人,题意为左手或右手有墙才能前进,否则左转,我们可以理解为左手无墙,便向左转,即能转就转,不能转则遍历其他方向。因为盲人行动有墙的限制,所以路线单一,找到一条路则为最短路径。

↑→←↓
对于左手盲人:方向为↑时,遍历方向应为←↑→↓,即顺时针方向遍历。右手盲人同理。我们可以用一个变量储存当前盲人方向。代码如下:

#include <stdio.h>
int n,m,q1,q2,w1,w2,head,tail,a1,b1,c1;
int next[4][2]={0,1,1,0,0,-1,-1,0};
int next1[4][2]={0,-1,-1,0,0,1,1,0};
int next2[4][2]={0,1,-1,0,0,-1,1,0};
int b[44][44];
char a[44][44];
struct dalao
{
    int x;
    int y;
    int s;
}st[1666];
void dfs1(int x,int y,int e,int d)
{
    int tx,ty,j;
    if(x==q2&&y==w2)
    {
        a1=e;
        return ;
    }
    for(int i=0;i<4;i++)
    {
        if(a1)	return ;
        j=(d-1+i+4)%4;
        tx=x+next1[j][0];
        ty=y+next1[j][1];
        if(tx<0||tx>=n||ty<0||ty>=m||a[tx][ty]=='#')
            continue;
        dfs1(tx,ty,e+1,j);
    }
}
void dfs2(int x,int y,int e,int d)
{
    int tx,ty,j;
    if(x==q2&&y==w2)
    {
        b1=e;
        return ;
    }
    for(int i=0;i<4;i++)
    {
        if(b1)	return ;
        j=(d-1+i+4)%4;
        tx=x+next2[j][0];
        ty=y+next2[j][1];
        if(tx<0||tx>=n||ty<0||ty>=m||a[tx][ty]=='#')
            continue;
        dfs2(tx,ty,e+1,j);
    }
}
void bfs(int q1,int w1)
{
    int tx,ty,ts;
    st[head].x=q1;
    st[head].y=w1;
    st[head].s=1;
    tail++;
    while(tail>head)
    {
        for(int i=0;i<4;i++)
        {
            tx=st[head].x+next[i][0];
            ty=st[head].y+next[i][1];
            ts=st[head].s+1;
            if(tx<0||tx>=n||ty<0||ty>=m||a[tx][ty]=='#'||b[tx][ty])
            	continue;
            b[tx][ty]=1;
            st[tail].x=tx;
            st[tail].y=ty;
            st[tail].s=ts;
            tail++;
            if(tx==q2&&ty==w2)
            {
                c1=st[tail-1].s;
                return ;
            }
        }
        head++;
    }
}
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=0;i<n;i++)
    {
        scanf("%s",a[i]);
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(a[i][j]=='S')
            {
                q1=i;
                w1=j;
            }
            if(a[i][j]=='E')
            {
                q2=i;
                w2=j;
            }
        }
    }
    dfs1(q1,w1,1,1);
    dfs2(q1,w1,1,1);
    bfs(q1,w1);
    printf("%d\n%d\n%d\n",a1,b1,c1);
    return 0;
}
posted @ 2020-03-05 17:40  键盘_书生  阅读(40)  评论(0编辑  收藏  举报