噴水裝置(二) nyoj
阿新 • • 發佈:2018-11-20
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<cmath> using namespace std; struct node{ double l;//裝置的左端點 double r;//裝置的右端點 }a[10001]; int com(struct node a,struct node b){ return a.l<b.l;//按照左端點排序 } int main(){ int n,m,w,h,x,r; scanf("%d",&n); while(n--){ scanf("%d%d%d",&m,&w,&h); double len,temp; for(int i=0;i<m;i++){ scanf("%d%d",&x,&r); len=(r*r)-(h/2)*(h/2); if(len>=0) temp=sqrt(len);//細節,注意 if(len<0) temp=0; a[i].l=x-temp; a[i].r=x+temp; } sort(a,a+m,com); double sum=0,max; int ans=0,flag=1; while(sum<w){ max=0; for(int i=0;i<m;i++){//每次都選擇最右端的裝置 if(sum>=a[i].l){//保證可以覆蓋左邊 if((a[i].r-sum)>max){ max=a[i].r-sum; } } } if(max==0){ flag=0; break; } else{ sum+=max; ans++; } } if(flag){ printf("%d\n",ans); } else{ printf("0\n"); } } return 0; } //思路按照噴水裝置所能到達的最左端開始排序,每次都選擇可以覆蓋左邊並且能到達最右邊的 //噴水裝置,當全部覆蓋時即完成,若找不到可以覆蓋左邊的裝置,則方案失敗。