列表

详情


OR175. 建物流中转站

描述

Shopee物流会有很多个中转站。在选址的过程中,会选择离用户最近的地方建一个物流中转站。

假设给你一个二维平面网格,每个格子是房子则为1,或者是空地则为0。找到一个空地修建一个物流中转站,使得这个物流中转站到所有的房子的距离之和最小。 能修建,则返回最小的距离和。如果无法修建,则返回 -1。


若范围限制在100*100以内的网格,如何计算出最小的距离和?

当平面网格非常大的情况下,如何避免不必要的计算?

输入描述

4
0 1 1 0
1 1 0 1
0 0 1 0
0 0 0 0

先输入方阵阶数,然后逐行输入房子和空地的数据,以空格分隔。

输出描述

8

能修建,则返回最小的距离和。如果无法修建,则返回 -1。

示例1

输入:

4
0 1 1 0
1 1 0 1
0 0 1 0
0 0 0 0

输出:

8

示例2

输入:

4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

输出:

-1

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 220KB, 提交时间: 2020-07-30

#include <stdio.h>
#include <stdlib.h>

int range(int p[100][100],int x, int y,int n)
{
   // p=(int *)malloc(sizeof(int)*n*n);
    int range_sum=0;
    for (int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(p[i][j]==1)
            range_sum+=(abs(x-i)+abs(y-j));
        }
    }
   // free(p);
    return range_sum;
}


/*
int main()
{
    int N;
    float x=0;
    float y=0;
    int count;
    scanf("%d",&N);
    int data[100][100];
   for(int i=0;i<N;i++)
    {  for(int j=0;j<N;j++)
        {
            scanf("%d",&data[i][j]);
            if(data[i][j]==1)
            {
                x+=i;
                y+=j;
                count++;
            }
        }
    }

   x = x / count;
    y = y / count;
    int range_1;
    int range_2;
    int range_3;
    range_1=range(data,x,y,N);
    range_2=range(data,x+1,y+1,N);
    range_3=range_1<range_2? range_1:range_2;
   // int range_1=range(data,x,y,N);
    //printf("%d",range(data,x, y,N)>range(data,x+1,y+1,N)?range(data,x+1,y+1,N):range(data,x,y,N));
        printf("%d",range_3);
    return 0;
}*/
///*
int Outcome(int Array[][100],int N,int x,int y)
{
    int i,j,way = 0;
       
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            if(Array[i][j] == 1)
            {
                way += abs(x - i);
                way += abs(y - j);
            }
        }
    }
   
    return way;
}
   
int main()
{
    float x,y;
    int N,i,j,X,Y,count = 0;
    int Array[100][100];
    int way,way1,way2;
    scanf("%d",&N);
   /* for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&Array[i][j]);
            if(Array[i][j] == 1)
            {
                x += i;
                y += j;
                count++;
            }
        }
    }*/
       for(int i=0;i<N;i++)
    {  for(int j=0;j<N;j++)
        {
            scanf("%d",&Array[i][j]);
            if(Array[i][j]==1)
            {
                x+=i;
                y+=j;
                count++;
            }
        }
    }
    if(count == 0)
    {
        printf("-1\n");
        return 0;
    }
    x = x / count;
    y = y / count;
    //way1 = Outcome(Array,N,x,y);
   // way2 = Outcome(Array,N,x+1,y+1);
       way1 = range(Array,x,y,N);
      way2 = range(Array,x+1,y+1,N);
    way = way1<way2?way1:way2;
    printf("%d",way);
       
    return 0;
}//*/

C++14 解法, 执行用时: 2ms, 内存消耗: 268KB, 提交时间: 2020-07-14

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>


int calDistance(int** arr, int n, int x, int y)
{
    int distance = 0, maxDistance = n * 2, sumDistance = 0, realX, realY;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (arr[i][j] == 0)
            {
                // 逼近理想距离
                distance = abs(x - i) + abs(y - j);
                if (distance < maxDistance)
                {
                    maxDistance = distance;
                    realX = i;
                    realY = j;
                }
            }
        }
    }

    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (arr[i][j] == 1)
            {
                sumDistance += (abs(realX - j) + abs(realY - i));
            }
        }
    }

    return sumDistance;
}

int main()
{
    int n, count = 0, result = -1, x = 0, y = 0;
    scanf("%d", &n);
    int** arr = (int **)malloc(n * sizeof(void *));
    for (int i = 0; i < n; ++i)
    {
        arr[i] = (int*)malloc(sizeof(int) * n);
    }

    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            scanf("%d", &arr[i][j]);
            if (arr[i][j] == 1)
            {
                x += j;
                y += i;
                ++count;
            }
        }
    }

    if (count < n * n)
    {
        // 计算理想的中心坐标
        x /= count;
        y /= count;

        // 计算距离和
        result = calDistance(arr, n, x, y);
        int tmp = calDistance(arr, n, x + 1, y + 1);
        if (result > tmp)
        {
            result = tmp;
        }
    }

    for (int i = 0; i < n; ++i)
    {
        free(arr[i]);
    }
    free(arr);

    printf("%d", result);

    return 0;
}

上一题