微軟編程之美2014初賽第一場#3

題目3 : 活動中心
時間限制:12000ms
單點時限:6000ms
內存限制:256MB
描述
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
3
1 1
2 2
3 3
樣例輸出

Case 1: 1.678787


問題分析:

該問題可以看做在一條直線一側有N個點,求N個點到直線上一點的距離和最短,由此我們根據座標系建立方程, N個點分別爲A1,A2,A3......An;直線上一點爲P(x,0)。那麼可以寫出方程距離和 d=∑ sqrt((Axi-x)^2+Ayi^2);這是一個關於x的一元二次方程,分析可得開口向上,存在最小值,該最小值在導數等於0時取得。因此,對該方程求導可得 ∑(Axi-x)/sqrt((Axi-x)^2+Ayi^2);這個式子的含義其實就是各個點與直線上一點的連線和座標軸構成的角的餘弦值和,因此餘弦和爲0的時候便是最小值了,找出x的值可以採用二分法。

#include<iostream>
#include<map>
#include<cmath>
#include<iomanip>
#define esp 1e-6
using namespace std;
map<int, int> m;
double check(double x){
	map<int, int>::iterator it;
	double sum = 0;
	double a, b;
	for (it = m.begin(); it != m.end(); ++it){
		a = it->first - x;
		b = it->second;
		sum += (a*1.0 / sqrt(a*a + b*b));
	}
	return sum;
}
int main(){
	int t;
	while (cin >> t){
		for (int i = 1; i <= t; i++){
			int n;
			cin >> n;
			for (int j = 0; j < n; j++){
				int a, b;
				cin >> a >> b;
				m[a] = b;
			}
			double l = m.begin()->first;
			map<int, int>::iterator itor = m.end();
			itor--;
			double r = itor->first;
			double mid = (l + r) / 2.0;
			double ans = check(mid);
			while (fabs(ans) > esp){
				if (ans > 0){
					l = mid;
					mid = (mid + r) / 2;
				}
				else{
					r = mid;
					mid = (mid + l) / 2;
				}
				ans = check(mid);
			}
			cout.setf(ios::fixed);
			cout.setf(ios::showpoint);
			cout.precision(6);
			cout << "Case " << i << ": " << mid << endl;
			m.clear();
		}
	}
}




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