Best Coder#4 B HDU 4932 Miaomiao's Geometry 解题报告
这个题在比赛的时候一直没敢做,,,后来交了一次也WA了 比赛的时候刚开始过了900+人然后最终测评只剩下21个过了的了 = = 细节决定成败阿,
首先 这个题有一个不好想到的点 就是 区间的长度可能为 *.5但是不会是别的小数了, 还有 区间可以一次覆盖两个点 ;
我的做法是这样的 简单利用贪心的思路吧 先把所有区间长度按照降序排序 ,然后枚举区间长度及区间一半长度,用fill函数来判断这个长度是否能满足题意,
fill的思想是 ,默认第一个和最后一个点已经标记上,然后扫描所有区间长度,如果区间能放入一个覆盖区间 那么优先覆盖左边的点(标记左边的点为覆盖状态 cov[i]=1)如果左边的点已被覆盖 那么就覆盖右边的点 思路是这样没问题的 我刚开始的时候忘记考虑优先标记问题,然后后来考虑了之后 ,又把代码写错了。。。。。用gdb调试才发现问题 细节问题
调试问题在 白色区域发现的 if 后第二个if忘了加 else 导致覆盖了第一个点之后又去覆盖第二个点
我自己在出测试数据的时候也只考虑了,如果我的算法错误是不是会导致这个区域覆盖不上,而没想同时也有可能导致不能覆盖的区间被覆盖 ,自己的思维还是不严密
AC代码如下
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<vector> 5 #include<cstring> 6 7 const double maxd=1e20; 8 double eps=1e-9; 9 10 using namespace std; 11 12 13 vector<int> v; 14 vector<double> vdis; 15 bool cov[1000]; 16 double dis[1000]; 17 18 int N; 19 bool cmp(int a,int b) 20 { 21 return a>b; 22 } 23 24 bool fill(double a) 25 { 26 bool ok=0; 27 memset(cov,0,sizeof(cov)); 28 cov[0]=1; 29 cov[N-1]=1; 30 for(int i=0;i<N-1;i++) 31 { 32 //if(dis[i]<a && dis[i+1]<a) return false; 33 //if(cov[i]==0 && dis[i]<2*a && dis[i]!=a && dis[i+1]<a) return false; 34 //if(dis[i]==a || dis[i]>=2*a){cov[i]=1;cov[i+1]=1;} 35 if(dis[i]>a) 36 { 37 if(cov[i]==0) 38 cov[i]=1; 39 else if(cov[i]==1) 40 cov[i+1]=1; 41 } 42 //if(dis[i]==a) {cov[i]=1;cov[i+1]=1;} 43 if((dis[i]-a)>-eps && (dis[i]-a)<eps) {cov[i]=1;cov[i+1]=1;} 44 if(dis[i]>=2*a) {cov[i]=1;cov[i+1]=1;} 45 } 46 for(int i=0;i<N;i++) 47 if(!cov[i]) return false; 48 return true; 49 } 50 51 52 53 int main(void) 54 { 55 int T; 56 int a; 57 cin>>T; 58 while(T--) 59 { 60 double res; 61 cin>>N; 62 v.clear(); 63 vdis.clear(); 64 int tt=N; 65 while(tt--) 66 { 67 cin>>a; 68 v.push_back(a); 69 } 70 sort(v.begin(),v.end()); 71 //cout<<"DEBUG"<<endl; 72 //for(vector<int>::iterator ii=v.begin();ii!=v.end();ii++) 73 // cout<<*ii<<" "; 74 //cout<<endl<<"DEBUGEND"<<endl; 75 int now; 76 int pre; 77 for(vector<int>::iterator ii =v.begin();ii!=v.end();ii++) 78 { 79 if(ii==v.begin()) 80 { 81 now=*ii; 82 pre=now; 83 } 84 else 85 { 86 now=*ii; 87 vdis.push_back(now-pre); 88 pre=now; 89 } 90 } 91 bool ok=1; 92 int count=0; 93 for(vector<double>::iterator ii=vdis.begin();ii!=vdis.end();ii++) 94 { 95 dis[count++]=*ii; 96 } 97 dis[count]=maxd; 98 sort(vdis.begin(),vdis.end(),cmp); 99 //cout<<"DEBUG"<<endl; 100 //for(vector<double>::iterator ii=vdis.begin();ii!=vdis.end();ii++) 101 // cout<<*ii<<" "; 102 //cout<<endl<<"DEBUGEND"<<endl; 103 count=0; 104 double max=-300; 105 for(vector<double>::iterator ii=vdis.begin();ii!=vdis.end();ii++) 106 { 107 count++; 108 if(count==N) break; 109 if(fill(*ii) && max<*ii) max=*ii; 110 //cout<<"max="<<max<<endl; 111 if(fill(*ii/2) && max<*ii/2) max=*ii/2; 112 //cout<<"max="<<max<<endl; 113 } 114 printf("%.3lf\n",max); 115 } 116 return 0; 117 }