噴水裝置(二)

2021-08-21 19:52:48 字數 1343 閱讀 5671

有一塊草坪,橫向長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

#include #include #include using namespace std;

struct use

a[10005];

int cmp(use l,use r)

int main()

else

}sort(a,a+n,cmp);

int ans=0,sum=0,flag=1;

while(summax)

max=a[i].right-sum;//每次都找出符合 a[i].left<=sum(即能和上乙個找出的圓的右邊接在一起)的圓中,有效灑水長度最長的圓,計算出新的灑水距離

} if(max==0)//如果新找出的最優圓有效灑水長度為0並且sum仍沒有達到w(草坪寬度),那往後就不可能完成覆蓋全部的草坪,退出迴圈,flag=0

else

}if(flag) printf("%d\n",ans);//符合條件的,輸出結果

else printf("0\n");//不存在的

}return 0;

}

題目分析:本題可以看作是區間覆蓋問題的乙個例子,只要對上述的內容稍微轉換以下即可,將每個圓的射擊範圍對映到區間內。可相應轉換為:數軸上有n個區間[ai,bi](這個指的是噴水裝置的合理的噴水區間),選擇盡量少的區間覆蓋一條指定線段[s,t](這個區間指的就是[0,w])。

貪心策略:

把各區間按照a從小到大排序,從前向後遍歷,然後每次選擇從當前起點s開始的最長區間,並以這個區間的右端點為新的起點,繼續選擇,直到找不到區間覆蓋當前起點s或者s已經到達線段末端。

需要注意的是,如果某一區間邊界大於s,t的邊界,應把它們變成s或t。因為超出的部分毫無意義,同時還會影響對資料的分析

噴水裝置 二

時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 有一塊草坪,橫向長w,縱向長為h,在它的橫向中心線上不同位置處裝有n n 10000 個點狀的噴水裝置,每個噴水裝置i噴水的效果是讓以它為中心半徑為ri的圓都被潤濕。請在給出的噴水裝置中選擇盡量少的噴水裝置,把整個草坪全部潤濕。...

噴水裝置(二)

時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 有一塊草坪,橫向長w,縱向長為h,在它的橫向中心線上不同位置處裝有n n 10000 個點狀的噴水裝置,每個噴水裝置i噴水的效果是讓以它為中心半徑為ri的圓都被潤濕。請在給出的噴水裝置中選擇盡量少的噴水裝置,把整個草坪全部潤濕。...

噴水裝置(二)

時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 有一塊草坪,橫向長w,縱向長為h,在它的橫向中心線上不同位置處裝有n n 10000 個點狀的噴水裝置,每個噴水裝置i噴水的效果是讓以它為中心半徑為ri的圓都被潤濕。請在給出的噴水裝置中選擇盡量少的噴水裝置,把整個草坪全部潤濕。...