建立信號基站-c#求解-英雄會在線編程題目

     看了下這道題,也覺得非常有意思,因此把這道題也寫一下。先上題目:

建立信號基站
  • 北京
  • 難 度 等 級:        
題目詳情

要建立一個信號基站服務n個村莊,這n個村莊用平面上的n個點表示。假設基站建立的位置在(X,Y),則它對某個村莊(x,y)的距離爲max{|X – x|, |Y – y|}, 其中| |表示絕對值,我們的目標是讓所有村莊到信號基站的距離和最小。

基站可以建立在任何實數座標位置上,也可以與某村莊重合。



 

輸入

給定每個村莊的位置x[],y[],x,y都是整數,滿足:

           -1000000000 < x,y < 1000000000

村莊個數大於1,小於101。

輸出

所有村莊到信號基站的距離和的最小值。

關於精度:

因爲輸出是double。我們這樣判斷對錯,如果標準答案是A,你的答案是a,如果|A – a| < 1e-3 我們認爲是正確的,否則認爲是錯誤的。


樣例

假設有4個村莊位置分別爲 (1,4) (2,3) (0,1) (1,1)

我們的結果是5。因爲我們可以選擇(1.5,2.5)來建立信號基站。

bestDistance = max(|1.5-1|, |2.5-4|) + max(|1.5-2|,|2.5-3|) + max(|1.5-0|,|2.5-1|) + max(|1.5-1|,|2.5-1|)

= max(0.5, 1.5) + max(0.5,0.5) + max(1.5,1.5) + max(0.5,1.5)

= 1.5 + 0.5 + 1.5 + 1.5

= 5

分析:

直管感覺就是,給一個大的框框,吧這些點全部框進去,那麼信號基站的座標肯定在這個框框中,呵呵。但是具體在哪裏呢?

進一步分析,是所有點到這個基站的x軸座標差,或者y軸座標差,誰大取誰。

 

這個就看出端倪了,在座標系中,y=x和y=-x,吧座標系劃分成4個部分,上下兩個部分中的點,y到原點的距離大於x到原點距離。因此,這個框框就很容易找到了。

也就是y=x和y=-x,進行平移,形成的這樣一個矩形的框框,平移的距離正好就是:x-y和x+y,其中最大值和最小值決定了這個矩形框框的邊界,所以,首先,找出最大值和最小值:這樣就有了處理過程:

int[] line1 = new int[x.Length];
            int[] line2 = new int[x.Length];
            for (int i = 0; i < x.Length; i++)
            {
                line1[i] = x[i] - y[i];
                line2[i] = x[i] + y[i];
            }
            int t = 0;
            for (int i = 0; i < line1.Length; i++)
            {
                for (int j = i + 1; j < line1.Length; j++)
                {
                    if (line1[i] > line1[j])
                    {
                        t = line1[j];
                        line1[j] = line1[i];
                        line1[i] = t;
                    }
                    if (line2[i] > line2[j])
                    {
                        t = line2[j];
                        line2[j] = line2[i];
                        line2[i] = t;
                    }
                }
            }

首先求出值,然後排下序。這裏爲了簡單,就使用的是冒泡排序法。當然你也可以使用高效點的排序方法。

這裏忘了說明一點:就是我們剛纔直管感覺,基站落在這個矩形裏面,爲什麼?大家自己分析下吧。這個很容易證明,矩形之外的點到矩形裏面的點的值肯定要大。

 

其實這個分析過程,也有助於進行第二步的分析,即找到基站的座標位置。

首先,在矩形的一邊上取某點,然後,沿着y=x的方向移動,我們會發現,當移動到此點所在的y=x+k時,這條直線劃分的點在上下兩邊一樣多的時候,距離值最小(自己可以很簡單的就證明了)

同理,當點移動到y=k-x直線,劃分的上下兩邊點相同時,距離最短,

 

有了這個分析,我們就是求k1和k2了

double line1K = 0;
            double line2K = 0;
            if (x.Length % 2 == 1)
            {
                line1K = line1[line1.Length / 2];
                line2K = line2[line2.Length / 2];
            }
            else
            {
                line1K = (line1[line1.Length / 2 - 1] + line1[line1.Length / 2 ])/2;
                line2K = (line2[line2.Length / 2 - 1] + line2[line2.Length / 2]) / 2;
            }

求出了k1,k2,那麼這兩條直線的交叉點就是基站的座標點了。

double x1 = (line1K + line2K) / 2;
            double y1 = (line2K - line1K) / 2;

剩下就是把距離求出來了。

這個拋出個問題:基站的位置是不是就一定是交叉點?顯然不是,當點的個數爲偶數時,其實,基站的位置是最裏面的四個點圍成的矩形。

 

至此,全部完成,提交,ok,沒問題。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章