貪心演算法之 噴水裝置二(nyoj12)

2021-07-02 01:48:32 字數 1485 閱讀 5962

題目描述:

時間限制:

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。

樣例輸入

2

2 8 6

1 14 5

2 10 6

4 56 5

樣例輸出

1

2

分析:這是貪心中區間覆蓋的問題:

數軸上有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個噴水裝置,...