題目描述:
Shopee物流會有很多箇中轉站。在選址的過程中,會選擇離用戶最近的地方建一個物流中轉站。假設給你一個二維平面網格,每個格子是房子則爲1,或者是空地則爲0。找到一個空地修建一個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。 能修建,則返回最小的距離和。如果無法修建,則返回 -1。
若範圍限制在100*100以內的網格,如何計算出最小的距離和?
當平面網格非常大的情況下,如何避免不必要的計算?
解釋:
暴力求解的思想就是直接根據問題來找答案。該問題可以直接轉換成再一個X、Y座標系中找到一個0點到所有1點的距離之和最小,而這裏的距離並不是兩點之間線段最短的距離。但可以用兩點之間線段最短的思想來解題,問題就轉化成了,只要能知道0點座標x1、y1和1點座標x2、y2即可求出兩點之間的距離來,再將所有1點到該0點的距離相加即可得到該0點到所有1點的距離之和了,將該距離值保存起來。當矩陣中所有0點到各個1點的距離和求完之後再從儲存的距離值中找到最小的那個值即爲最小距離和。目的很明確,方法也很容易想到,根據每一步的目的簡單明瞭的求解。
代碼:
/**
暴力求解:
該方法的思想很簡單,直接遍歷每一個0位置到每一個1位置的距離之和,再將這些
距離和組成一個數組,再遍歷該數組得到一個最小值即爲最小距離和
**/
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int N;//確定矩陣的大小
int a[105][105];//存放矩陣
double b[10001];//存放假設每一個空地建造中轉站時各個城市到該地的最短距離, 這裏數組要聲明的大一點,不然會溢出
int count1=0;//用於記錄存放於矩陣中的數據中1的個數
cout<<"請輸入矩陣大小:";
cin>>N;
cout<<endl;
cout<<"請輸入矩陣的值:\n";
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
cin>>a[i][j];
if(a[i][j]==1)
{
count1++;
}
}
}
cout<<endl;
//該部分用於計算每一個可用於建造中轉站的點到城市的距離之和,並存儲於數組b中,用於後續選出最短距離和
int count=0;
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(a[i][j]==0)
{
int x1=i;//記錄爲可以建造中轉站的地點的x座標
int y1=j;//記錄爲可以建造中轉站的地點的y座標
double lenSum=0;//用於累加中轉站到每一個城市的距離
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(a[i][j]!=0)
{
int x2=i;//記錄城市的x座標
int y2=j;//記錄塵世的y座標
lenSum+=sqrt((x1-x2)*(x1-x2))+sqrt((y1-y2)*(y1-y2));//累加每一個1到該0位置的距離
}else{
lenSum+=0;
}
}
}
b[count]=lenSum;
count++;
}
}
}
//該部分用於判斷矩陣是否全爲1
if(count1==N*N)
{
cout<<"無法建造中轉站";
//cout<<-1;
}
else{
double temp=9999999;//用於選出b數組中的最短距離
for(int i=0;i<count;i++)
{
if(b[i]<temp)
{
temp=b[i];
}
else{
temp=temp;
}
}
int minlength = (double)temp;//強制轉換double---->int
cout<<"最短距離和爲:";
cout<<minlength;
}
return 0;
}