首页 > 代码库 > 【刷水-二分答案】BZOJ1650-[Usaco2006 Dec]River Hopscotch 跳石子

【刷水-二分答案】BZOJ1650-[Usaco2006 Dec]River Hopscotch 跳石子

【题目大意】

数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次条都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子,问移走这M个石子后,相邻两个石子距离的最小值的最大值是多少。

*0和L也是两块石头!

【思路】

二分最小值检验即可。二分都是套路,然而我写错了,烧 杯 把ub敲成了l,忘记了范围其实是[lb,ub)QAQ

检验部分的套路:last记录上一次跳到的石头,只要当前石头和上一次的石头的距离小于dis,那么就移走这块石头。如果移走的石头>m,就说明不可行。这是目前看来最简洁的写法了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int MAXN=50000+50;
 7 int l,n,m,d[MAXN];
 8 
 9 int check(int dis)
10 /*这种检验方式在贪心中经常使用*/
11 {
12     int last=0,tmp=0;
13     for (int i=1;i<=n;i++)
14     {
15         if (d[i]-d[last]<dis)
16         {
17             tmp++;
18             if (tmp>m) return 0;
19         }
20         else last=i;
21     } 
22     return 1;
23 }
24 
25 void init()
26 {
27     scanf("%d%d%d",&l,&n,&m);
28     for (int i=1;i<=n;i++) scanf("%d",&d[i]);
29     sort(d+1,d+n+1);
30     d[0]=0;
31     d[++n]=l;
32 }
33 
34 void bisearch()
35 {
36     int lb=0,ub=l+1;
37     while (lb+1<ub)
38     {
39         int mid=(lb+ub)>>1;
40         if (check(mid)) lb=mid;
41             else ub=mid;
42     }
43     printf("%d",lb);
44 }
45 
46 int main()
47 {
48     init();
49     bisearch();
50     return 0;
51 }

 

【刷水-二分答案】BZOJ1650-[Usaco2006 Dec]River Hopscotch 跳石子