hdu 4004 二分 2011大连赛区网络赛D

题意:一个长为L的河,中间有n个石子,小青蛙需要跳少于m次过河,判断小青蛙每次跳跃最大距离的最小值

最大值最小,用二分

Sample Input
6 1 2
2
25 3 3
11
2
18
Sample Output
4
11
 
2015-07-27:备战区域赛专题
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****\n");
15 const int MAXN=500010;
16 int n,m,tt,L;
17 int a[MAXN];
18 int check(int m)
19 {
20     int tot=0;
21     int k=0;    //目前待的石头
22     int w=0;
23     while(tot<L)
24     {
25         int o=k+1;
26         if(a[o]-a[k]>m)
27         {
28             return 0;
29         }
30         while(m>=a[o]-a[k])
31         {
32             o++;
33         }
34         k=o-1;
35         tot+=a[o]-a[k];
36         w++;
37     }
38     return w;
39 }
40 int main()
41 {
42     int i,j,k;
43     #ifndef ONLINE_JUDGE
44     freopen("1.in","r",stdin);
45     #endif
46     while(~scanf("%d%d%d",&L,&n,&m))
47     {
48         for(i=1;i<=n;i++)    scanf("%d",&a[i]);
49         a[0]=0;
50         a[n+1]=L;
51         sort(a,a+n+2);
52         a[n+2]=100000001;
53         int l=0,r=L;
54         int ans=0;
55         while(l<=r)
56         {
57             int mid=(r+l)>>1;
58             if(check(mid)&&check(mid)<=m)
59             {
60                 ans=mid;
61                 r=mid-1;
62             }
63             else l=mid+1;
64         }
65         printf("%d\n",ans);
66     }
67 }
View Code

 

 
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=500010;
 9 int n,m,t,L;
10 int d[maxn];
11 bool fun(int x) //判断青蛙跳x的时候需要跳几次过河,贪心,每次选择能跳最远的
12 {
13     int now=0,tot=0;
14     int cnt=0;
15     while(now<L)
16     {
17         now+=x;
18         while(now>=d[tot])   tot++;
19         now=d[tot-1];
20         cnt++;
21     }
22     if(cnt<=m)  return true;
23     else return false;
24 }
25 int main()
26 {
27     int i,j,k;
28     //freopen("1.in","r",stdin);
29     while(scanf("%d%d%d",&L,&n,&m)!=EOF)
30     {
31         for(i=1;i<=n;i++)   scanf("%d",&d[i]);
32         sort(d+1,d+n+1);
33         d[0]=0;
34         d[n+1]=L;
35         d[n+2]=100000001;   //用来判断跳几次过河的边界
36         int l=0,r=L,mid;
37         int ans;    //记录最小值
38         for(i=1;i<=n+1;i++) l=l<d[i]-d[i-1]?d[i]-d[i-1]:l;  //求出两个相邻石子之间的最大距离,也就是青蛙要跳的最小距离
39         while(l<=r)
40         {
41             mid=(l+r)>>1;
42             if(fun(mid))    ans=mid,r=mid-1;
43             else l=mid+1;
44         }
45         printf("%d\n",ans);
46     }
47 }

 

posted @ 2015-07-27 17:16  miao_a_miao  阅读(147)  评论(0)    收藏  举报