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[]以前排序。
-
1
-
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 }
-