poj 3258 River Hopscotch(二分+贪心)

题目:http://poj.org/problem?id=3258

题意:

一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L。

河中有n块石头,每块石头到S都有唯一的距离

问现在要移除m块石头(S和E除外),每次移除的是与当前最短距离相关联的石头,

要求移除m块石头后,使得那时的最短距离尽可能大,输出那个最短距离。

和3273差不多。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 50000+10;
 8 int a[maxn];
 9 
10 int main()
11 {
12     int l, n, m, i;
13     int low, mid, high, sum, cnt;
14     cin>>l>>n>>m;
15     a[n+1] = l;
16     low = l;
17     high = l;
18     for(i = 1; i <= n; i++)
19     {
20         cin>>a[i];
21     }
22     sort(a+1, a+n+1);
23     for(i = 1; i <= n+1; i++)
24     if(a[i]-a[i-1]<low)
25         low = a[i]-a[i-1];
26 
27     while(high>=low) //注意‘=’号
28     {
29         sum = 0; cnt = 0;
30         mid = (high+low)/2;
31         for(i = 1; i <= n+1; i++)
32         {
33             sum += a[i]-a[i-1];
34             if(sum<mid)
35             cnt++;
36             else
37             sum = 0;
38         }
39         if(cnt<=m)   //注意‘=’号
40         low = mid+1;
41         else
42         high = mid-1;
43     }
44     cout<<high<<endl;
45     return 0;
46 }

 

 

以后还是用这种形式的二分吧

while(left<right)

{

if()

left=mid+1;

else right=mid;

}

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 50000+1000;
 8 int a[maxn];
 9 
10 int main()
11 {
12     int l, n, m, i, f;
13     int low, mid, high, sum, cnt;
14     cin>>l>>n>>m;
15     a[n+1] = l;
16     low = l;
17     high = l;
18     for(i = 1; i <= n; i++)
19     {
20         cin>>a[i];
21     }
22     sort(a+1, a+n+1);
23     for(i = 1; i <= n; i++)
24     if(a[i]-a[i-1]<low)
25         low = a[i]-a[i-1];
26 
27     f = 0;
28     while(high>low)
29     {
30         sum = 0; cnt = 0;
31         mid = (high+low)/2;
32         for(i = 1; i <= n; i++)
33         {
34             sum += a[i]-a[i-1];
35             if(sum<mid)
36             cnt++;
37             else
38             sum = 0;
39         }
40         if(cnt > m)
41         {
42             high = mid;
43             f = 1;
44         }
45         else
46         low = mid+1;
47         //cout<<low<<endl<<high<<endl;
48     }
49     if(f)
50     cout<<high-1<<endl;
51     else
52     cout<<high<<endl;
53     return 0;
54 }

 

还有http://blog.csdn.net/jackyguo1992/article/details/8665202

这篇博客以这两道题为例, 说明了二分时的易错的情况

posted @ 2014-03-17 20:39  水门  阅读(150)  评论(0编辑  收藏  举报