贪心算法之——喷水装置二(nyoj12)
生活随笔
收集整理的這篇文章主要介紹了
贪心算法之——喷水装置二(nyoj12)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述:
噴水裝置(二)
時間限制:3000?ms ?|? 內存限制:65535?KB 難度:4 描述每一組測試數據的第一行有三個整數n,w,h,n表示共有n個噴水裝置,w表示草坪的橫向長度,h表示草坪的縱向長度。
隨后的n行,都有兩個整數xi和ri,xi表示第i個噴水裝置的的橫坐標(最左邊為0),ri表示該噴水裝置能覆蓋的圓的半徑。
如果不存在一種能夠把整個草坪濕潤的方案,請輸出0。
這是貪心中區間覆蓋的問題:
數軸上有n個閉區間[ai,bi],選擇盡量少的區間覆蓋一條指定線段[s,t].(而這一題的變化在于要先對數據進行處理把圓心和半徑,轉換成區間的[ai,bi])
本題的突破口在與區間包含和排序掃描,把各區間按照a從小到大排序。如果區間1的起點不是<=s,無解(因為其他區間的起點更大,不可能覆蓋到s點),否則選擇起點在s(或s之前)的右端點b最大的區間。選擇此區間[ai,bi]后,新的起點應該設置為s=bi。然后繼續向后掃描,直到所有區間掃描完畢,判斷選擇的最后一個區間的右端點bi是否小于t,小于則無解。
源碼:
#include <stdio.h> #include <math.h> #include <algorithm> using namespace std; typedef struct line {double left, right; }Line;bool cmp(Line l1,Line l2) {return l1.left < l2.left; } int main() {int t;scanf("%d", &t);while(t--){Line l[10005]={0};int n, w, h;double x, r;scanf("%d%d%d", &n, &w, &h);for(int i=0; i<n; i++){scanf("%lf%lf", &x, &r);if(2*r>h){double temp = sqrt(r*r-h*h/4.0);l[i].left = x-temp;l[i].right = x+temp;}}sort(l, l+n, cmp);double start=0.0;if(l[0].left>start) puts("0"); //如果區間1的起點不是<=start,無解else{int i=0,max=0,cnt=0;while(1){for(; i<n; i++){if(l[i].left<=start){//選擇起點在start(或start之前)的右端點b最大的區間if(l[i].right>l[max].right) max = i; }else break;}start = l[max].right;if(l[i].left>start) {puts("0"); break;}cnt++;//判斷選擇的最后一個區間的右端點bi是否小于w,小于則無解。if(i==n && l[max].right<w) {puts("0"); break;} if(start>=w) {printf("%d\n", cnt); break;}}}} return 0; }
題目鏈接:http://acm.nyist.net/JudgeOnline/problem.php?pid=12
總結
以上是生活随笔為你收集整理的贪心算法之——喷水装置二(nyoj12)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爱奇艺程序员落户北京后离职被判赔 10
- 下一篇: Logback 整合 RabbitMQ