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 }

posted on 2017-03-06 22:15  Dark猫  阅读(146)  评论(0)    收藏  举报

导航