長l公尺,寬w公尺的草坪裡裝有n個澆灌噴頭。每個噴頭都裝在草坪中心線上(離兩邊各w/2公尺)。我們知道每個噴頭的位置(離草坪中心線左端的距離),以及它能覆蓋到的澆灌範圍。
請問:如果要同時澆灌整塊草坪,最少需要開啟多少個噴頭?
輸入包含若干組測試資料。
第一行乙個整數t表示資料組數。
每組資料的第一行是整數n、l和w的值,其中n≤10 000。
接下來的n行,每行包含兩個整數,給出乙個噴頭的位置和澆灌半徑。
如圖1所示的示意圖是樣例輸入的第一組資料所描述的情況。
對每組測試資料輸出乙個數字,表示要澆灌整塊草坪所需噴頭數目的最小值。如果所有噴頭都開啟還不能澆灌整塊草坪,則輸出-1。
3
8 20 2
5 34 1
1 27 2
10 2
13 3
16 2
19 4
3 10 1
3 59 3
6 13 10 1
5 31 1
9 1
6
2-1
對於100%的資料,n≤15000。
由於噴水器的噴水半徑不一樣,且每個噴水器的座標也不同,所直接採用座標貪心或者採用半徑大小貪心都不太合適,這裡採用每個噴水器在草坪邊緣的兩個交點來排序。
設每個噴水器i都會和草坪的一條邊相交於兩點lefti和righti,那麼我們對所有節點,對lefti由小到大排序,如果lefti大小相同,則按照righti由大到小排。
在排序前其實應該判斷lefti的最小值是否大於0,若最小的lefti都大於0,那麼肯定不可能把草坪全部潤濕,同時判斷最大的righti和草坪的長的關係。同時把left和right均小於0或者均大於草坪長的噴水器去掉,因為根本用不上。這樣得到的若干噴水器就是合法噴水器的組合。
根據left值從小向大找,其中left小於0且right值最大的那個節點肯定是第乙個需要的噴水器,這樣當該噴水器去掉之後,該噴水器的邊緣到草坪的右邊緣就構成了乙個新的問題,再重複上面的步驟即可。
#include
#include
#include
struct penpen[
15000];
intcmp
(pen x,pen y)
using
namespace std;
intmain()
sort
(pen,pen+n,cmp)
;int count =0;
double star =
0.0,last;
//last先記錄右座標然後再傳遞給last
for(
int i=
0;i) star = last;
//star記錄滿足條件的下乙個裝置的右座標
i--;//退回,準備繼續尋找下乙個滿足條件的裝置
count++;}
if(star >= w)
//star現在為座標右點,若大於則說明已經全部覆蓋
break;}
if(star >= w)
cout << count <
else
cout <<
"-1"
<
}return0;
}
噴水裝置 貪心演算法
時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述現有一塊草坪,長為20公尺,寬為2公尺,要在橫中心線上放置半徑為ri的噴水裝置,每個噴水裝置的效果都會讓以它為中心的半徑為實數ri 0 輸入第一行m表示有m組測試資料 每一組測試資料的第一行有乙個整數數n,n表示共有n個噴水裝置,...
噴水裝置(一)貪心演算法
聽說這是 貪心演算法 的乙個簡單應用,雖說是簡單,但是對我來說,確實不簡單。說下面說有用的 題目描述 現有一塊草坪,長為20公尺,寬為2公尺,要在橫中心線上放置半徑為ri的噴水裝置,每個噴水裝置的效果都會讓以它為中心的半徑為實數ri 0輸入描述 第一行m表示有m組測試資料 每一組測試資料的第一行有乙...
貪心演算法(一) 噴水裝置(一)
時間限制 3000 ms 記憶體限制 65535 kb 難度 3描述 現有一塊草坪,長為20公尺,寬為2公尺,要在橫中心線上放置半徑為ri的噴水裝置,每個噴水裝置的效果都會讓以它為中心的半徑為實數ri 0輸入 第一行m表示有m組測試資料 每一組測試資料的第一行有乙個整數數n,n表示共有n個噴水裝置,...