Codeforces 782B The Meeting Place Cannot Be Changed
题目链接:http://codeforces.com/contest/782/problem/B
题意:给出n个人在y轴上的坐标xi和最大速度vi,他们可向上或向下以不超过最大速度的速度移动,求所有人相遇的最小时间t是多少。
做法:
二分即可。可二分坐标也可二分时间。
赛场上想到了二分,但是二分写错了,WA了好多次。
写搓的代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<vector> 5 #include<set> 6 #include<map> 7 #include<cstring> 8 #include<iostream> 9 #include<cmath> 10 #include<stack> 11 #define DEBUG 12 using namespace std ; 13 const double eps = 1e-9; 14 struct Point 15 { 16 long long int x ; 17 long long int v ; 18 } a[100000]; 19 20 bool cmp( struct Point a , struct Point b ) 21 { 22 if( a.x < b.x ) 23 return true ; 24 return false ; 25 } 26 double abbss( double a ) 27 { 28 if( a >= eps ) 29 return a ; 30 else 31 return (-a); 32 } 33 int main() 34 { 35 int n ; 36 scanf("%d",&n); 37 for( int i = 1 ; i <= n ; i++) 38 scanf("%lld",&a[i].x); 39 for( int i = 1 ; i <= n ; i++) 40 scanf("%lld",&a[i].v); 41 sort(a+1,a+1+n,cmp); 42 double l = 0.0 , r = 1e9 , mid = ( l + r ) / 2 ; 43 double minn = 1e9; 44 while( r - l > eps ) 45 { 46 double templ = -1000; 47 double tempr = -1000; 48 double tempmid = -1000; 49 for( int i = 1 ; i <= n ; i++) 50 { 51 templ = max( templ ,fabs( (double) ( l + mid) / 2 - a[i].x ) / a[i].v ); 52 tempr = max( tempr ,fabs( (double) (r + mid) / 2 - a[i].x ) / a[i].v ) ; 53 tempmid = max( tempmid ,fabs( (double) (r + mid) / 2 - a[i].x ) / a[i].v ) ; 54 } 55 56 if( minn - templ >= eps ) 57 minn = templ ; 58 if( minn - tempr >= eps ) 59 minn = tempr; 60 if( minn - tempmid >= eps ) 61 minn = tempmid ; 62 if( templ - tempr <= eps ) 63 { 64 r = mid ; 65 mid = ( l + r ) / 2 ; 66 } 67 else 68 { 69 l = mid ; 70 mid = ( l + r ) / 2 ; 71 } 72 } 73 74 printf("%.12lf\n",minn); 75 return 0 ; 76 }
错误原因: 二分应该找一个很容易判断哪边小的情况二分,我这种写法其实是种偷懒,二分的是坐标,可里面计算的是时间。
xjb调了半天,最后越调越不像。(下次遇到这种情况应该果断换思路重写,这次主要肯定了正解是二分于是一直在调细节,认为自己大体没错)。
下次二分一定要找能明显判断哪部分是正确答案所在部分!!!!
下次二分一定要找能明显判断哪部分是正确答案所在部分!!!!
下次二分一定要找能明显判断哪部分是正确答案所在部分!!!!
避免出现这种,两边都比中间小,然后我还想要怎么判断,是找更小的还是更大的那个……
看了题解后发现自己错误。
最后AC代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<vector> 5 #include<set> 6 #include<map> 7 #include<cstring> 8 #include<iostream> 9 #include<cmath> 10 #include<stack> 11 using namespace std ; 12 const double eps = 1e-9 ; 13 struct point 14 { 15 int x,v; 16 } a[100000]; 17 18 bool cmp( struct point a , struct point b ) 19 { 20 return a.x < b.x ; 21 } 22 23 int main() 24 { 25 int n ; 26 scanf("%d",&n); 27 for( int i = 1 ; i <= n ; i++) 28 scanf("%d",&a[i].x); 29 for( int i = 1 ; i <=n ; i++) 30 scanf("%d",&a[i].v); 31 sort(a+1,a+n+1,cmp); 32 double l = a[1].x , r = a[n].x , mid = (l+r) / 2 ; 33 double minn = ( ( l == r) ? 0 : 1e10 ); // 这里是考虑坐标全部一样的情况,WA了一次 34 while( r - l > eps ) 35 { 36 double lmax = 0 , rmax = 0; 37 for( int i = 1 ; i <= n ; i++) 38 { 39 if( a[i].x < mid ) 40 lmax = max( lmax , (double)(mid - a[i].x )/ a[i].v); 41 if( a[i].x > mid ) 42 rmax = max( rmax , (double)( a[i].x - mid) / a[i].v) ; 43 } 44 45 double temp ; 46 temp = max( lmax , rmax ); 47 minn = min( minn , temp ) ; 48 49 50 if( lmax > rmax ) 51 { 52 r = mid ; 53 mid = ( l + r ) / 2 ; 54 } 55 else if( fabs( lmax - rmax ) <= eps ) 56 { 57 break ; 58 } 59 else 60 { 61 l = mid ; 62 mid = ( l + r ) / 2 ; 63 } 64 } 65 66 printf("%.12lf\n",minn); 67 return 0 ; 68 69 }

浙公网安备 33010602011771号