题目: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
这篇博客以这两道题为例, 说明了二分时的易错的情况