与修路的那个题一样,只不过是需要将青蛙每次跳的重新存到数组里面。
青蛙过河 | ||||||
| ||||||
Description | ||||||
青蛙王国一年一度的游戏又开始了,这个游戏要求青蛙必须跳过河。河的宽度是 L 。河里有n块石头,这n块石头从河的一边笔直的连到另一边。青蛙只能踩着石头过河,如果它们掉到水里,将被淘汰出局。游戏规定青蛙最多跳m次。现在青蛙想要知道如果在这m步内跳到岸的那边,它一步最长需要跳多长。 | ||||||
Input | ||||||
输入包括多组测试结果。 第一行输入三个数字L(1<= L <= 1000 000 000),n(0<= n <= 500000),m(1<= m <= n+1)。 接下来一行有n个用空格隔开的整数,表示每块石头到跳跃起点的距离,两块石头不可能同时出现在一个地方。 | ||||||
Output | ||||||
对于每次测试,输出一个整数表示青蛙至少应该有的最大的能力,即为一步最多能跳多长,每步实际跳的长度一定小于等于这个最小的最大能力。 | ||||||
Sample Input | ||||||
6 1 2 2 25 3 3 11 2 18 | ||||||
Sample Output | ||||||
4 11 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 const int MAX = 500010; 5 6 int dis[MAX]; 7 int changedis[MAX]; 8 9 int cmp(const void *a, const void *b) 10 { 11 return *(int*)a - *(int*)b; 12 } 13 14 int check(int left, int right, int *p, int h, int m) 15 { 16 while (left < right) 17 { 18 int mid = (left + right) / 2; 19 int tmp = p[0]; 20 int x = m-1; 21 for (int i=1; i<h; i++) 22 { 23 if (tmp + p[i] <= mid) 24 { 25 tmp += p[i]; 26 } 27 else 28 { 29 tmp = p[i]; 30 x--; 31 } 32 } 33 if (x < 0) 34 { 35 left = mid + 1; 36 } 37 else 38 { 39 right = mid; 40 } 41 } 42 return left; 43 } 44 45 int main(void) 46 { 47 int l; 48 int n; 49 int m; 50 51 while (scanf("%d", &l) != EOF) 52 { 53 54 55 scanf("%d%d", &n, &m); 56 57 for (int i=0; i<n; i++) 58 { 59 scanf("%d", &dis[i]); 60 } 61 qsort(dis, n, sizeof(dis[0]),cmp);//先按远近排个序 62 63 int left = 0; 64 changedis[0] = dis[0]; 65 left = dis[0]; 66 for(int i=1; i<n; i++)//处理数组,重新存起来。 67 { 68 changedis[i] = dis[i] - dis[i-1]; 69 if (changedis[i] > left) 70 { 71 left = changedis[i]; 72 } 73 } 74 changedis[n] = l - dis[n-1]; 75 if (changedis[n] > left) 76 { 77 left = changedis[n]; 78 } 79 80 int res = check(left, l, changedis, n+1, m); 81 printf("%d\n", res); 82 } 83 return 0; 84 }
|