1. 程式人生 > >|NOIOJ|二分|04:網線主管

|NOIOJ|二分|04:網線主管

描述

仙境的居民們決定舉辦一場程式設計區域賽。裁判委員會完全由自願組成,他們承諾要組織一次史上最公正的比賽。他們決定將選手的電腦用星形拓撲結構連線在一起,即將它們全部連到一個單一的中心伺服器。為了組織這個完全公正的比賽,裁判委員會主席提出要將所有選手的電腦等距離地圍繞在伺服器周圍放置。

為購買網線,裁判委員會聯絡了當地的一個網路解決方案提供商,要求能夠提供一定數量的等長網線。裁判委員會希望網線越長越好,這樣選手們之間的距離可以儘可能遠一些。

該公司的網線主管承接了這個任務。他知道庫存中每條網線的長度(精確到釐米),並且只要告訴他所需的網線長度(精確到釐米),他都能夠完成對網線的切割工作。但是,這次,所需的網線長度並不知道,這讓網線主管不知所措。

你需要編寫一個程式,幫助網線主管確定一個最長的網線長度,並且按此長度對庫存中的網線進行切割,能夠得到指定數量的網線。

輸入 第一行包含兩個整數N和K,以單個空格隔開。N(1 <= N <= 10000)是庫存中的網線數,K(1 <= K <= 10000)是需要的網線數量。
接下來N行,每行一個數,為庫存中每條網線的長度(單位:米)。所有網線的長度至少1m,至多100km。輸入中的所有長度都精確到釐米,即保留到小數點後兩位。 輸出 網線主管能夠從庫存的網線中切出指定數量的網線的最長長度(單位:米)。必須精確到釐米,即保留到小數點後兩位。
若無法得到長度至少為1cm的指定數量的網線,則必須輸出“0.00”(不包含引號)。 樣例輸入
4 11
8.02
7.43
4.57
5.39
樣例輸出
2.00

依然二分題,注意以下幾個細節:

1、由於精度問題,把輸入資料*100放入整數陣列

2、r要在最長電線上+1,因為會出現整條電線用完的情況

Ps:WA了幾次就因為這兩問題。

參考程式碼:

#include<cstdio>
int n,k; 
int a[10200];
int l=0, mid, r=0;
void init() {
	scanf("%d%d", &n, &k);
	for (int i=1;i<=n;i++) {
		double t;
		scanf("%lf", &t);
		a[i] = (float)(t*100.0);
		if (a[i]>r) r=a[i];
	} 
	r++;
}
int check(int x) {// 比f多 return 1
	int ans=0;
	for (int i=1;i<=n;i++) {
		ans += a[i] / x;
	}
	if (ans>=k) return 1; else return 0; 
}
void go() {
	while (l+1<r) {
		mid = (l+r)/2;
		if (check(mid)) l=mid; else r=mid;
	}
	printf("%.2lf", l / 100.0); 
}
int main() {	
	init();
	go();
	return 0;
}