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 }

 

你可能感兴趣的:(HDU)