sdf1434 最少转弯


主页
讨论版
问题
名次
状态
统计

问题 C: 最少转弯

时间限制: 1 Sec  内存限制: 128 MB
提交: 394  解决: 143
[提交][状态][讨论版]

题目描述

给出一张地图,这张地图被分为n×m(n,m<=100)个方块,任何一个方块不是平地就是高山。平地可以通过,高山则不能。现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能到达目的地(x2,y2)?你只能沿着水平和垂直方向的平地上行进,拐弯次数就等于行进方向的改变(从水平到垂直或从垂直到水平)的次数。

例如:如图1,最少的拐弯次数为5。

输入:共三行

第一行:n   m

第2至n+1行:整个地图地形描述(0:空地;1:高山),

如(图1)第2行地形描述为:1 0 0 0 0 1 0

第3行地形描述为:0 0 1 0 1 0 0

……

最后放在同一行。

第n+2行:x1 y1 x2 y2 (分别为起点、终点坐标)

输出:s (即最少的拐弯次数)

输入

输出

样例输入

5 7
1 0 0 0 0 1 0 
0 0 1 0 1 0 0 
0 0 0 0 1 0 1 
0 1 1 0 0 0 0 
0 0 0 0 1 1 0
1 3 1 7

样例输出

5

提示


要改为优先队列,先出队拐弯最少的。 可以在头脑里面想象一条激光,射到的地方都要先找


#include<cstdio>

#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;

int m,n;
const int MAXN=1000;
int a[MAXN][MAXN];//存地图
int vis[MAXN][MAXN];//存标记
int dir[4][2] = {
    { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }
};

struct node {
    int x;
    int y;
    int fx;//方向
    int len;//拐弯次数
    //优先小的先来
    bool operator< (const node &a)const {
        return len > a.len;
    }
};


/*
5 7
1 0 0 0 0 0 0
0 0 1 0 1 0 0
0 0 0 1 1 1 0
0 1 0 1 0 0 0
1 0 0 0 0 0 0
1 3 5 2

2


*/
int sx,sy,tx,ty;

int bfs(int i, int j)
{
    priority_queue<node> q;
    //找到一个队列头
    vis[i][j]=1;
    q.push({i, j, -1, 0});//初始节点方向设为特殊值-1,表示可以任何方向

    //所有相关的全部入队搜索
    while(!q.empty())
    {
        auto f=q.top();
        q.pop();
        //找到
        if(f.x==tx && f.y==ty)
        {
            return f.len;
        }

        int nx,ny,nfx,nlen;
        for(int k=0;k<4;k++)//枚举四个方向
        {
            nx=f.x+dir[k][0];
            ny=f.y+dir[k][1];
            nfx=k;
            if(f.fx!=-1 && nfx!=f.fx)//和原来方向不同,拐弯一次。初始节点-1特殊判断
                nlen=f.len+1;
            else
                nlen=f.len;

            if(nx<0 || nx>=m || ny<0 || ny>=n)
                continue;
            if(a[nx][ny]==0 && !vis[nx][ny])
            {
                vis[nx][ny]=1;
                q.push({nx, ny, nfx, nlen});
            }
        }
    }
    return -1;

}

int main()
{  
    cin>>m>>n;
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
        {
            char c;
            cin>>c;
            a[i][j]=c-'0';
        }
    cin>>sx>>sy>>tx>>ty;
    sx--;sy--;tx--;ty--;//坐标偏移1

    int min_len = bfs(sx,sy);
    cout<<min_len<<endl;

    return 0;
}



posted on 2021-10-19 16:02  katago  阅读(24)  评论(0编辑  收藏  举报