喷水装置(二) 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;
}
//思路按照喷水装置所能到达的最左端开始排序,每次都选择可以覆盖左边并且能到达最右边的
//喷水装置,当全部覆盖时即完成,若找不到可以覆盖左边的装置,则方案失败。 

猜你喜欢

转载自blog.csdn.net/chan_yeol/article/details/52413263
今日推荐