編程之美初賽第一場
題目3 : 活動中心
時間限制:12000ms 單點時限:6000ms 內存限制:256MB- 例子輸入
-
1 3 1 1 2 2 3 3
- 例子輸出
-
Case 1: 1.678787
描寫敘述
A市是一個高度規劃的城市。可是科技高端發達的地方,居民們也不能忘記運動和鍛煉,因此城市規劃局在設計A市的時候也要考慮為居民們建造一個活動中心。方便居住在A市的居民們能隨時開展運動。鍛煉強健的身心。
城市規劃局希望活動中心的位置滿足下面條件:
1. 到全部居住地的總距離最小。
2. 為了方便活動中心的資源補給和其它器材的維護,活動中心必須建設在A市的主幹道上。
為了簡化問題。我們將A市擺在二維平面上,城市的主幹道看作直角坐標系平的X軸,城市中全部的居住地都能夠看成二維平面上的一個點。
如今。A市的城市規劃局希望知道活動中心建在哪兒最好。
輸入
第一行包含一個數T。表示數據的組數。
接下來包括T組數據,每組數據的第一行包括一個整數N。表示A市共同擁有N處居住地
接下來N行表示每處居住地的坐標。
輸出
對於每組數據。輸出一行“Case X: Y”,當中X表示每組數據的編號(從1開始)。Y表示活動中心的最優建造位置。我們建議你的輸出保留Y到小數點後6位或以上,不論什麽與標準答案的絕對誤差或者相對誤差在10-6以內的結果都將被視為正確。
數據範圍
小數據:1 ≤ T ≤ 1000, 1 ≤ N ≤ 10
大數據:1 ≤ T ≤ 10, 1 ≤ N ≤ 105
對於全部數據。坐標值都是整數且絕對值都不超過106
例子解釋
例子1:活動中心的最優建造位置為(1.678787, 0)
1、對目標函數求導。目標函數是 y=((x-x1)^2+y1*y1)^1/2+((x-x2)^2+y2*y2)^1/2+...,我們的目標是找到它的最小值,對它求導後,令導數等於0,此時的 x 就是我們要找的目標函數極小值處的 x 。可是導數=0也不好解。繼續對導數求導發現其是恒大於0的,也就是說導數是遞增的。所以導數的值應該是由負到正變化的,故目標函數應該是先遞減後遞增,有極小值,我們對導數應用二分法,找到它等於0處的點;關鍵代碼例如以下:
while(fabs(l-h)>= 0.00000001){ mid= (l+h)/2; if(calcu(mid)){ //計算導數值是否 >=0,若是。繼續往右找 h= mid; }else{ //否則。往左找 l= mid; } }
//calcu函數關鍵部分。求導數值
for(int i= 0; i< len; ++i){ a= mid-point[i].first; b= sqrt(a*a+(point[i].second*point[i].second)); sum+=a/b; }
return sum>=0;
2、看到還有一位網友說,能夠用三分法(我還是頭一次聽說這個三分法。。),即找一個全局的中間點mid,再找一個右半部分的mid,比較二者的目標函數值。誰小就往那邊移動邊界;
double midl,midr,le,re,lme,rme; while(maxX-minX>eps) { midl=(minX+maxX)/2; //全局mid midr=(midl+maxX)/2; //右半段的mid,故為三分 lme=GetDis(midl); //計算目標函數值,即距離之和 rme=GetDis(midr); if(lme>rme) minX=midl; else maxX=midr; }
參考鏈接:
http://blog.csdn.net/kunlong0909/article/details/24120343
http://www.tuicool.com/articles/iEjMBzv
http://94it.net/a/jingxuanboke/2014/0419/302083_2.html
編程之美初賽第一場