第1部分 基礎算法(提高篇)--第1章 貪心算法1424:【例題3】噴水裝置

1424:【例題3】噴水裝置

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2916 通過數: 572
【題目描述】
長 L 米,寬 W 米的草坪裏裝有 n 個澆灌噴頭。每個噴頭都裝在草坪中心線上(離兩邊各 W2 米)。我們知道每個噴頭的位置(離草坪中心線左端的距離),以及它能覆蓋到的澆灌範圍。
在這裏插入圖片描述
請問:如果要同時澆灌整塊草坪,最少需要打開多少個噴頭?

【輸入】
輸入包含若干組測試數據。

第一行一個整數 T 表示數據組數;

每組數據的第一行是整數 n、L 和 W;

接下來的 n 行,每行包含兩個整數,給出一個噴頭的位置和澆灌半徑(上面的示意圖是樣例輸入第一組數據所描述的情況)。

【輸出】
對每組測試數據輸出一個數字,表示要澆灌整塊草坪所需噴頭數目的最小值。如果所有噴頭都打開也不能澆灌整塊草坪,則輸出 −1 。

【輸入樣例】
3
8 20 2
5 3
4 1
1 2
7 2
10 2
13 3
16 2
19 4
3 10 1
3 5
9 3
6 1
3 10 1
5 3
1 1
9 1
【輸出樣例】
6
2
-1
【提示】
數據範圍:

對於 100% 的數據,n≤15000。


思路:本題用貪心算法來解,結構體存每個噴頭的前後到達位置;以前端位置排序;

一個個掃描可以到達之前的後端,並且自己可以到達最遠的後端;分析不成立的情況;在這裏插入圖片描述
由於曲線不好處理,所以我們可以將覆蓋面積近似的看成是圖中紅色矩形覆蓋的面積(這樣對結果不造成影響)那麼這個矩陣的左端點與大區間最左側的距離爲 x - √[r^ 2-(h/2) ^ 2],矩形的右端點與大區間最左側的距離爲x + √[r^ 2 - (h/2)^2];

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;

int n,cnt,L,h,x,r;
struct node{
	double x;
	double y;
}a[20005];
bool cmp(node a, node b){
	return a.x < b.x;
} 
void read(){
	cin >> n >> L >> h;
	cnt = 0;
	for(int i = 1; i <= n; i++)
	{
		cin >> x >> r;
		if(r <= h/2) continue; //cnt是有用的裝置的個數,條件爲r>h/2
		cnt++;
		a[cnt].x = x - sqrt(r*r - h*h/4.0);
		a[cnt].y = x + sqrt(r*r - h*h/4.0);
	}
	
}
void solve(){
	double t = 0;
	int ans = 0,flag1 = 1, i = 1;
	while(t < L){
		ans++;
		double s = t;
		for(;a[i].x <= s&&i <= cnt;i++)//依次找到覆蓋l的最大右端 
		if(t < a[i].y) 
		t = a[i].y;
		if(t == s && s <L)
		{
			cout << -1 << endl;
			flag1 = 0;
			break;
		 } 
	}
	if(flag1) cout << ans << endl;
}

int main(){
	int T;
	cin >> T;
	while(T--){
		read();
		sort(a+1,a+1+cnt,cmp);
		solve();
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章