題目描述:
時間限制:
3000 ms | 記憶體限制:
65535 kb
難度:4 描述
有一塊草坪,橫向長w,縱向長為h,在它的橫向中心線上不同位置處裝有n(n<=10000)個點狀的噴水裝置,每個噴水裝置i噴水的效果是讓以它為中心半徑為ri的圓都被潤濕。請在給出的噴水裝置中選擇盡量少的噴水裝置,把整個草坪全部潤濕。
輸入第一行輸入乙個正整數n表示共有n次測試資料。
每一組測試資料的第一行有三個整數n,w,h,n表示共有n個噴水裝置,w表示草坪的橫向長度,h表示草坪的縱向長度。
隨後的n行,都有兩個整數xi和ri,xi表示第i個噴水裝置的的橫座標(最左邊為0),ri表示該噴水裝置能覆蓋的圓的半徑。
輸出每組測試資料輸出乙個正整數,表示共需要多少個噴水裝置,每個輸出單獨佔一行。
如果不存在一種能夠把整個草坪濕潤的方案,請輸出0。
樣例輸入
22 8 6
1 14 5
2 10 6
4 56 5
樣例輸出
12
分析:這是貪心中區間覆蓋的問題:
數軸上有n個閉區間[ai,bi],選擇盡量少的區間覆蓋一條指定線段[s,t].
(而這一題的變化在於要先對資料進行處理把圓心和半徑,轉換成區間的[ai,bi])
本題的突破口在與區間包含和排序掃瞄,把各區間按照a從小到大排序。如果區間1的起點不是<=s,無解(因為其他區間的起點更大,不可能覆蓋到s點),否則選擇起點在s(或s之前)的右端點b最大的區間。選擇此區間[ai,bi]後,新的起點應該設定為s=bi。然後繼續向後掃瞄,直到所有區間掃瞄完畢,判斷選擇的最後乙個區間的右端點bi是否小於t,小於則無解。
原始碼:
#include #include #include using namespace std;
typedef struct line
line;
bool cmp(line l1,line l2)
int main()
; int n, w, h;
double x, r;
scanf("%d%d%d", &n, &w, &h);
for(int i=0; ih)
}sort(l, l+n, cmp);
double start=0.0;
if(l[0].left>start) puts("0"); //如果區間1的起點不是<=start,無解
else
else break;
}start = l[max].right;
if(l[i].left>start)
cnt++;
//判斷選擇的最後乙個區間的右端點bi是否小於w,小於則無解。
if(i==n && l[max].right=w)
}} }
return 0;
}
貪心演算法(二) 噴水裝置(二)
時間限制 3000 ms 記憶體限制 65535 kb 難度 4描述 有一塊草坪,橫向長w,縱向長為h,在它的橫向中心線上不同位置處裝有n n 10000 個點狀的噴水裝置,每個噴水裝置i噴水的效果是讓以它為中心半徑為ri的圓都被潤濕。請在給出的噴水裝置中選擇盡量少的噴水裝置,把整個草坪全部潤濕。輸...
噴水裝置 貪心演算法
長l公尺,寬w公尺的草坪裡裝有n個澆灌噴頭。每個噴頭都裝在草坪中心線上 離兩邊各w 2公尺 我們知道每個噴頭的位置 離草坪中心線左端的距離 以及它能覆蓋到的澆灌範圍。請問 如果要同時澆灌整塊草坪,最少需要開啟多少個噴頭?輸入包含若干組測試資料。第一行乙個整數t表示資料組數。每組資料的第一行是整數n ...
噴水裝置 貪心演算法
時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述現有一塊草坪,長為20公尺,寬為2公尺,要在橫中心線上放置半徑為ri的噴水裝置,每個噴水裝置的效果都會讓以它為中心的半徑為實數ri 0 輸入第一行m表示有m組測試資料 每一組測試資料的第一行有乙個整數數n,n表示共有n個噴水裝置,...