時間限制: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;
}