1. 程式人生 > >噴水裝置(二) nyoj

噴水裝置(二) nyoj

#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;
}
//思路按照噴水裝置所能到達的最左端開始排序,每次都選擇可以覆蓋左邊並且能到達最右邊的
//噴水裝置,當全部覆蓋時即完成,若找不到可以覆蓋左邊的裝置,則方案失敗。