nyoj 12 喷水装置(二)(贪心)

 

喷水装置(二)

时间限制: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:(错误代码)
View Code
 1  
 2  
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define N 10010
 8 
 9 using namespace std;
10 
11 struct point{double s,e;}a[N];
12 bool flag[N];
13 double w,h;
14 
15 bool cmp(point A,point B)
16 {
17     if(A.s<B.s) return true;
18     if(A.s==B.s&&A.e<=B.e) return true;
19     return false;
20 }
21 
22 int work(int n)
23 {
24     int ans,i;
25     point p,max;
26     for(i=0;i<n;i++) 
27         if(flag[i])
28         {
29             p=max=a[i];break;
30         }
31     if(i==n||p.s>0)  return 0;
32     ans=1;
33     for(;i<n;)
34     {
35         if(max.e==w) return ans;
36         for(;a[i].s<=p.e&&i<n;i++)
37         {
38             if(flag[i]==false) continue;
39             if(a[i].e>max.e)
40                 max=a[i];
41         }
42         if(p.e==max.e) return 0;
43         if(p.s==max.s)
44         {
45             p=max;continue;
46         }
47         p=max;
48         ans++;
49     }
50     return ans;
51 }
52 
53 int main()
54 {
55     int test,n,i;
56     double x,r,t;
57     cin>>test;
58     while(test--)
59     {
60         cin>>n>>w>>h;
61         memset(flag,true,sizeof(flag));
62         for(i=0;i<n;i++) a[i].e=a[i].s=0;//一定要初始化,不然排序时会混乱的
63         for(i=0;i<n;i++)
64         {
65             cin>>x>>r;
66             if(r<=h/2)
67             {
68                 flag[i]=false;continue;
69             }
70             t=sqrt(r*r-h*h/4.0);
71             a[i].s=x-t;
72             a[i].e=x+t;
73             if(a[i].s<0) a[i].s=0;
74             if(a[i].e>w) a[i].e=w;
75         }
76         sort(a,a+n,cmp);
77         cout<<work(n)<<endl;
78     }
79     return 0;
80 }                

错误原因是,flag数组在标记后,没有和结构体a[]以前排序。

3 10 0

5 5 0 0 0 0

过不了 

代码2:

View Code
 1  
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N 10010
 7 
 8 using namespace std;
 9 
10 struct point{double s,e;}a[N];
11 double w,h;
12 
13 bool cmp(point A,point B)
14 {
15     if(A.s<B.s) return true;
16     if(A.s==B.s&&A.e<=B.e) return true;
17     return false;
18 }
19 
20 int work(int n)
21 {
22     int ans,i;
23     point p,max;
24     p=max=a[0];
25     if(p.s>0)  return 0;
26     ans=1;
27     for(i=1;i<n;)
28     {
29         if(max.e==w) return ans;
30         for(;a[i].s<=p.e&&i<n;i++)
31         {
32             if(a[i].e>max.e)
33                 max=a[i];
34         }
35         if(p.e==max.e) return 0;
36         if(p.s==max.s&&p.e<max.e)
37         {
38             p=max;continue;
39         }
40         p=max;
41         ans++;
42     }
43     return ans;
44 }
45 
46 int main()
47 {
48     int test,n,m,i,ans;
49     double x,r,t;
50     cin>>test;
51     while(test--)
52     {
53         cin>>n>>w>>h;
54         for(i=0,m=0;i<n;i++)
55         {
56             cin>>x>>r;
57             if(r<=h/2) continue;
58             t=sqrt(r*r-h*h/4.0);
59             a[m].s=x-t;
60             a[m].e=x+t;
61             if(a[m].s<0) a[m].s=0;
62             if(a[m].e>w) a[m].e=w;
63             m++;
64         }
65         if(m>0) 
66         {
67             sort(a,a+m,cmp);
68             ans=work(n);
69         }
70         else ans=0;
71         cout<<ans<<endl;
72     }
73     return 0;
74 }
75         

代码1与代码2只有在标记不同,代码1是把不符合条件的标记,代码2是直接去掉;

代码3:也是代码1的改进减少冗余

View Code
 1  
 2  
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define N 10010
 8 
 9 using namespace std;
10 
11 struct point{double s,e;}a[N];
12 double w,h;
13 
14 bool cmp(point A,point B)
15 {
16     if(A.s<B.s) return true;
17     if(A.s==B.s&&A.e<=B.e) return true;
18     return false;
19 }
20 
21 int work(int n)
22 {
23     int ans,i;
24     point p,max;
25     for(i=0;i<n;i++) 
26         if(a[i]!=0)
27         {
28             p=max=a[i];break;
29         }
30     if(i==n||p.s>0)  return 0;
31     ans=1;
32     for(;i<n;)
33     {
34         if(max.e==w) return ans;
35         for(;a[i].s<=p.e&&i<n;i++)
36         {
37             if(a[i].e>max.e)
38                 max=a[i];
39         }
40         if(p.e==max.e) return 0;
41         if(p.s==max.s)
42         {
43             p=max;continue;
44         }
45         p=max;
46         ans++;
47     }
48     return ans;
49 }
50 
51 int main()
52 {
53     int test,n,i;
54     double x,r,t;
55     cin>>test;
56     while(test--)
57     {
58         cin>>n>>w>>h;
59         for(i=0;i<n;i++) a[i].e=a[i].s=0;//一定要初始化,不然排序时会混乱的
60         for(i=0;i<n;i++)
61         {
62             cin>>x>>r;
63             if(r<=h/2)
64             {
65                 continue;
66             }
67             t=sqrt(r*r-h*h/4.0);
68             a[i].s=x-t;
69             a[i].e=x+t;
70             if(a[i].s<0) a[i].s=0;
71             if(a[i].e>w) a[i].e=w;
72         }
73         sort(a,a+n,cmp);
74         cout<<work(n)<<endl;
75     }
76     return 0;
77 }                

 代码4:RuntimeError 错误不明

View Code
 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #define N 10010
 5 
 6 using namespace std;
 7 
 8 struct point{double s,e;}a[N];
 9 
10 bool Comp(point A,point B)
11 {
12     if(A.s<B.s) return true;
13     if(A.s==B.s&&A.e<=B.e) return true;
14     return false;
15 }
16 
17 int main()
18 {
19     int test,n,i,m,ans;
20     double x,r,w,h,t;
21     point p,max;
22     cin>>test;
23     while(test--)
24     {
25         cin>>n>>w>>h;
26         ans=0;m=0;
27         for(i=0;i<n;i++)
28         {
29             cin>>x>>r;
30             if(r<=h/2) continue;
31             t=sqrt(r*r-h*h/4);
32             a[m].s=x-t;
33             a[m].e=x+t;
34             if(a[m].s<0) a[m].s=0;
35             if(a[m].e>w) a[m].e=w;
36             m++;
37         }
38         if(m>0) sort(a,a+m,Comp);
39         else
40         {
41             cout<<0<<endl;continue;
42         }
43         p=max=a[0];ans=1;
44         i=1;
45         while(i<m)
46         {
47             if(max.e==w) break;
48             while(a[i].s<=p.e&&i<m)
49             {
50                 if(a[i].e>max.e)max=a[i];
51                 i++;
52             }
53             if(max.e<=p.e)
54             {
55                 ans=0;break;
56             }
57             if(p.s<max.s) ans++;
58             p=max;
59         }
60         cout<<ans<<endl<<endl;
61     }
62     return 0;
63 }

 

 
posted @ 2012-04-19 01:09  mtry  阅读(1929)  评论(0编辑  收藏  举报