BFS非常詳細解題-1478-水路距離

1478 水陸距離

時間限制:10000ms
單點時限:1000ms
內存限制:256MB
描述
給定一個N x M的01矩陣,其中1表示陸地,0表示水域。對於每一個位置,求出它距離最近的水域的距離是多少。

矩陣中每個位置與它上下左右相鄰的格子距離爲1。

輸入
第一行包含兩個整數,N和M。

以下N行每行M個0或者1,代表地圖。

數據保證至少有1塊水域。

對於30%的數據,1 <= N, M <= 100

對於100%的數據,1 <= N, M <= 800

輸出
輸出N行,每行M個空格分隔的整數。每個整數表示該位置距離最近的水域的距離。

樣例輸入
4 4
0110
1111
1111
0110
樣例輸出
0 1 1 0
1 2 2 1
1 2 2 1
0 1 1 0

題意:

題意很簡單,就是讓你找從1開始到0的最短路徑。

寫給自己的:

打比賽的時候沒考慮清楚時間複雜度,這是一個及其不好的習慣,要改。
想着bfs和dfs搜索最短路徑,立馬寫了dfs,但超時了,改了改代碼,依舊超時,顯然當時腦子wtl。(這幾天狀態,做事不夠用心,批評一下自己)所以,今天重新寫了一遍。
因爲這題目是bfs。
然後打算bfs,但是不夠時間寫了。

解題:
其實顯然就是一個bfs的板子題。但實際並不是簡單得一下子就做出來的題目。
但是對於這個題目,一開始你可能會直接從1開始搜索,那麼肯定超時。

所以我們不能從1人開始搜索,優化一下從0開始搜索。

思路: BFS,先把糖果放入隊列,然後同時搜索,就像是病毒擴散一樣。
比如
0110
1111
1111
0110
搜索
以&代表沒有搜索,以0代表搜索過的點。
開始
0&&0
&&&&
&&&&
0&&0
第一步
0000
0&&0
0&&0
0000
第二步:
0000
0000
0000
0000
把沒一個搜索到的1,記錄在ans數組中,每次搜索過的點標記。也就是ans!=-1的點。當然是0的點也是一個 開始就要處理的點。

反思提升:

1.時間複雜度的考慮

對於這個題目給出的數據範圍是800*800
時間複雜度極限 :800 * 800 * 800
給出的時間又是 1s

對於dfs的時間複雜度顯然是很大很大的,因爲dfs的遞歸式搜索,要找到每一最小路徑,dfs是每一條路徑找出取最小路徑。
就算是BFS,如果按照從1開始搜索,也會超時。

2.選擇算法,這題顯然bfs。
3.考慮優化
4.確定思路,確定算法
5.檢查代碼,數據範圍,初始化。

提升:
代碼的寫法。

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<string.h>
#include<algorithm>
#include<queue>
#define pi acos(-1.0)
#define MaxN  0x3f3f3f3f
#define MinN  0xc0c0c0c0
using namespace std;
typedef long long ll;
const int N=1e3+10;
char s[N][N];
int n,m;
int ans[N][N];
int dis[4][2]= {1,0,0,1,-1,0,0,-1}; //方向
struct node
{
    int x,y,step;
}st,en;
queue<node>q;
int judge()//判斷條件
{
    if(en.x<0||en.x>=n||en.y<0||en.y>=m||ans[en.x][en.y]!=-1)
    {
        return 1;
    }
    return 0;
}
void bfs()
{
    while(!q.empty())
    {
        st=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            en.x=st.x+dis[i][0];
            en.y=st.y+dis[i][1];
            if(judge())
                continue;
            en.step=st.step+1;
            ans[en.x][en.y]=en.step;
            q.push(en);
        }
    }
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%s",s[i]);
    }
    memset(ans,-1,sizeof(ans));
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(s[i][j]=='0')//先找出所有位‘0’的座標,優化
            {
                st.x=i;
                st.y=j;
                st.step=0;
                ans[i][j]=0;//一開始就處理了0的點
                q.push(st);//進隊列
            }
        }
    }
    bfs();
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            printf("%d ",ans[i][j]);
        }
        printf("\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章