nyoj 12 喷水装置(二)
2016-02-13 23:36
465 查看
喷水装置(二)
时间限制:3000 ms | 内存限制:65535 KB难度:4
描述有一块草坪,横向长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 1 4 5 2 10 6 4 5 6 5
样例输出
1 2
代码:
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int x[100010],r[100010];//x表示喷水装置坐标,r表示覆盖半径 struct record { double start;//每个喷水装置覆盖范围的起点 double end;//覆盖范围的终点 }num[100010]; bool cmp(record a,record b) { if(a.start!=b.start) return a.start<b.start; else return a.end>b.end; }//按起点升序排列,如果起点相同,按终点降序排列 int main() { int T,n,w,h,i,j,k,l,f,g,contact,sum;//sum计数,contact表示接上一装置且最优的装置。 double he,chang;//chang表示两个相邻喷水装置的终点之差,he表示当前喷水装置所能覆盖的长度 scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&w,&h); f=0,g=0,k=0; for(i=0;i<n;i++) { scanf("%d%d",&x[i],&r[i]); if(r[i]>(double)h/2) { num[k].start=x[i]-sqrt(r[i]*r[i]-(double)h*h/4); if(num[k].start<0) { num[k].start=0; } num[k].end=x[i]+sqrt(r[i]*r[i]-(double)h*h/4); if(num[k].start==0) f=1; if(num[k].end>=w) g=1; k++; } } if(f==0||g==0) printf("0"); else { sort(num,num+k,cmp); sum=0,contact=1; for(i=0;i<k;i+=(contact-i)) { chang=0; l=0; he=num[i].end; sum++; if(he>=w) break; for(j=i+1;j<k;j++) { if((num[j].start<=num[i].end)&&(num[j].end-num[i].end>chang)) { chang=num[j].end-num[i].end; contact=j; l=1; } } if(l==0) break; } if(he>=w) printf("%d",sum); else printf("0"); } printf("\n"); } return 0; }
相关文章推荐
- 四大域对象
- Java的四种引用
- Unity Android 不显示阴影
- Linux相关书籍下载
- 常用语言的api大全
- 利用多张图片实现动态图
- GOKit全缓动类型gif列表
- POJ 3067 Japan
- 【Bootstrap基础学习】00 序
- Service详解
- LintCode Subtree
- 【DIV+CSS】中央定位
- 【shiro】shiro学习笔记2-自定义realm
- 【Gym 100712A】Who Is The Winner?
- 【URAL刷题记】 URAL 1090~URAL 1097
- 学习c++的五十条忠告
- Java模板引擎 FreeMarker
- 腰椎间盘突出&腰椎间盘膨出的锻炼方法
- python-webpy和mongodb实现博客统计
- 利用KVO监听属性值的变化