坦然玲子  

 

喷水装置(二)

时间限制: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
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<math.h>
 5 
 6 using namespace std;
 7  struct SS
 8 {
 9   int a;
10   int b;
11 }s[10002];
12 
13 bool cmp(struct SS p1,struct SS p2)
14 {
15   if(p1.a<p2.a)
16    return true;
17  if(p1.a==p2.a&&p1.b<=p2.b) return true;
18     return false;
19 }
20 
21 int main()
22 {
23   int t,n,w,h,i,j,k,x,r,count,max;
24 
25   cin>>t;
26   while(t--)
27   {
28     cin>>n>>w>>h;
29  k=0;
30  max=-1;
31  for(i=0;i<n;i++)
32  {
33    cin>>x>>r;
34    if(r>h/2)
35    {
36      s[k].a=x-sqrt(r*r-(h/2)*(h/2));
37      s[k].b=x+sqrt(r*r-(h/2)*(h/2));
38   if(s[k].a<0)//预处理去掉无效的部分,【0,w】之外的
39    s[k].a=0;
40   if(s[k].b>w)
41    s[k].b=w;
42   if(s[k].b>max)
43    max=s[k].b;
44             k++;
45    }
46  }
47  //cout<<s[0].a<<" "<<max<<endl;
48    sort(s,s+k,cmp);
49    if(s[0].a!=0||max!=w)//这种情况无解
50    {
51     cout<<"0"<<endl;
52     continue;
53    }
54    count=0;
55       int f=0;
56    int start=0,last=0;
57    while(start!=w)
58    {
59      for(i=f; i<k; i++)
60    if(s [i].a<=start&&s[i].b>last)
61    {
62      last=s[i].b;
63      f=i+1;
64    }
65     if(last==start)//这种情况也无解
66     {
67       count=0;
68    break;
69     }
70     start=last;//从新定义边界
71     count++;
72    }
73    cout<<count<<endl;
74   }
75   return 0;
76 }

 

posted on 2012-03-13 15:47  坦然玲子  阅读(766)  评论(0编辑  收藏  举报