hihocoder比赛的时候临时有事,没有答题。后来看到了这一题,第一反应就是广度优先搜索。 当时的想法是,从每个水域0开始进行广度优先搜索。到达某个点A后,查找上下左右未被访问过的的最小值,然后将这个值+1就是这个点A位置的最小值。若周围都是未访问过的点,就将A重新塞回队列。写好后,结果居然TLE了。仔细想了想,发现其实在某个点A去访问周围点的时候,周围点的距离=A点距离+1,而不需要跑到周围点上再次进行判断了。改了以后,就AC了。
下面贴代码(LeetCode风格):
//水陆距离
#include<iostream>
#include<string>
#include<queue>
#include<stdio.h>
using namespace std;
#define Num 820
#define Max 2000
int result[Num][Num];
bool flag[Num][Num];
char Map[Num][Num];
int zhuanhuan[4][2] = { { -1,0 },{ 1,0 },{0,-1 },{ 0,1 } };
class cor {
public:
int X;
int Y;
cor(int x = 0, int y = 0) :X(x), Y(y)
{
}
};
class Solution {
public:
int FindHi()
{
int N = 0, M = 0, k = 0;
queue<cor> LittleHi;
cin >> N >> M;//输入N M
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> Map[i][j];
if (Map[i][j] == '0') {
result[i][j] = 0;
LittleHi.push(cor(i, j));//将0点塞入队列
}
else
{
result[i][j] = Max;//其他点为MAX
}
}
}
while (!LittleHi.empty())
{
//result[LittleHi.front().X][LittleHi.front().Y] = Max;
int X = LittleHi.front().X, Y = LittleHi.front().Y;
for (k = 0; k < 4; k++)
{
int x = X + zhuanhuan[k][0];
int y = Y + zhuanhuan[k][1];
if (result[x][y] < Max || Map[x][y] == '0' || x >= N || y >= M || x < 0 || y < 0) continue;
//未访问过,不是0,在边界内
result[x][y] = result[X][Y] + 1;
LittleHi.push(cor(x, y));//周围点放入队列中
}
LittleHi.pop();
}
//输出
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cout << result[i][j] << " ";
}
cout << endl;
}
return 0;
}
};
int main()
{
Solution sol;
sol.FindHi();
system("pause");
return 0;
}
如有问题,欢迎讨论