你现在手里有一份大小为 N x N 的「地图」(网格) grid,上面的每个「区域」(单元格)都用 0 和 1 标记好了。其中 0
代表海洋,1 代表陆地,请你找出一个海洋区域,这个海洋区域到离它最近的陆地区域的距离是最大的。
我们这里说的距离是 「曼哈顿距离」(> Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 -> y1| 。
这道题我的思路是:
以0那点为中心,向两边搜索,比较求最短距离。
假设(x,y)这点为 ‘0’;
第一步:固定y不动,上下移动x,寻找 ‘1’,当找到第一个1的时候,直接跳出循环,节省运行时间。在(x,y)正上下方搜索。
第二步:向(x,y)两侧进行搜索, 寻找 ‘1’。
(1) 左侧, 左侧又分为左上部分和左下部分。
同样,也是固定y,来移动x。
左上部分: (x-j,y-1)·······(x-j,y-i)- - - i,j表示从0开始的值
左下部分: (x+j,y-1)·······(x+j,y-i)- - - i,j表示从0开始的值
(2)右侧相同。
第三步:比较这几部分中到(x,y)的距离,取最小值。
第四步:寻找一个最大值,也就是让全部 '0’执行上面三步,得到的值,取其中最大的那个,即为所求值。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int find_min(int arr[][3], int sz_row, int sz_col,int x,int y)
//这个函数是求一个0到1的最小距离。
{
int i = 0;
int j = 0;
int ret = 0;
int a = 0;
int b = 0;
for (i = 1; x - i >= 0 || x + i < sz_row; i++)
//y不变,在'0'的正上下方搜'1'
{
if (x - i >= 0)
{
if (arr[x - i][y] == 1)
{
ret = i;
break;
}
}
if ( x + i < sz_row)
{
if (arr[x + i][y] == 1)
{
ret = i;
break;
}
}
}
for (i = 1; y-i >=0 ; i++)//在左半部分搜'1' -- 固定y,移动x
{
for (j = 0; x-j>=0 || x+j<sz_row; j++)
{
if ( x - j >= 0)//左上部分
{
if (arr[x - j][y - i] == 1)
{
a = i + j;
break;
}
}
if (x + j < sz_row)//左下部分
{
if (arr[x + j][y - i] == 1)
{
a = i + j;
break;
}
}
}
if (b<a && b == 0)//保留左部分的最小值
{
b = a;
}
else if (b>a)
{
b = a;
}
}
if ((b < ret || ret == 0) && b != 0)//保留小的值
{
ret = b;
}
a = 0;
b = 0;
for (i = 1; y + i<sz_col; i++) //在右半部分搜'1' --固定y,移动x
{
for (j = 0; x - j>=0 || x + j<sz_row; j++)//右上部分
{
if (x - j >= 0)
{
if (arr[x - j][y + i] == 1)
{
a = i + j;
break;
}
}
if (x + j < sz_row)//右下部分
{
if (arr[x + j][y + i] == 1)
{
a = i + j;
break;
}
}
}
if (b<a && b == 0)//保留右部分的最小值
{
b = a;
}
else if (b>a)
{
b = a;
}
}
if ((b < ret || ret == 0) && b != 0)//保留小的值
{
ret = b;
}
return ret;
}
int maxDistance(int grid[][3], int gridSize, int* gridColSize)
{
int i = 0;
int j = 0;
int ret = 0;
int a = 0;
for (i = 0; i < gridSize; i++)
{
for (j = 0; j < *gridColSize; j++)
{
if (grid[i][j] == 0)//找'0'
{
a = find_min(grid, gridSize, *gridColSize,i,j);
if (ret < a)//保留距离远的值
{
ret = a;
}
}
}
}
if (ret == 0)//ret = 0 证明全是0或者1
{
return -1;
}
else
return ret;
}
int main()
{
int arr[][3] = { { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
int a = sizeof(arr) / sizeof(arr[0]);
int b = sizeof(arr[0]) / sizeof(arr[0][0]);
int ret = maxDistance(arr, a, &b);
printf("%d\n", ret);
return 0;
}
本人菜鸟,这段代码还能优化,把左边和右边合并在一起写。