# 跳石头二分算法总结



## 题目描述



在给定的长度 `L` 和 `N` 个书的位置 `a` 中，要求在这些书的位置之间放置 `M` 个分隔符，使得每两个相邻分隔符之间的最小距离最大化。需要找出这个最大最小距离。



## 输入格式



1. 第一行：三个整数 `L`（长度）、`N`（书的数量）、`M`（分隔符的数量）。
2. 第二行：`N` 个整数，表示书的位置。



## 输出格式



- 输出一个整数，表示最大化的最小距离。



## 算法思路



1. **初始化**：定义数组 `a` 存储书的位置，使用二分查找来确定最大最小距离。
2. **检查函数 `check`**：判断在给定的最小距离 `x` 的情况下，能否放置 `M` 个分隔符。
3. **二分查找**：在区间 `[0, L + 1]` 中进行二分查找，逐步逼近最大最小距离。



## C语言实现



以下是转换后的 C 语言代码：



```c
c#include <stdio.h>

const int N1 = 1e5 + 5;
int L, N, M;
int a[N1];

int check(int x) {
    int cnt = 0, now = 0;
    for (int i = 1; i <= N; ++i) {
        if (a[i] - now < x) {
            cnt++;
        } else {
            now = a[i];
        }
    }
    return cnt <= M;
}

int main() {
    scanf("%d %d %d", &L, &N, &M);
    for (int i = 1; i <= N; ++i) {
        scanf("%d", &a[i]);
    }
    int l = 0, r = L + 1, mid;
    while (l < r) {
        mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid + 1;
        } else {
            r = mid;
        }
    }
    printf("%d\n", r - 1);
    return 0;
}
c
```



## 逻辑解析



- **数组声明**：`int a[N1];` 用于存储书籍位置。
- **检查函数**：`check(int x)` 用于判断当前最小距离 `x` 是否可行，计算需要的分隔符数量。
- **二分查找**：
  - 初始化左右边界 `l` 和 `r`。
  - 通过 `mid` 值来逐步查找最大最小距离，更新边界 `l` 或 `r` 以收敛到解。
- **结果输出**：最终输出最大最小距离 `r - 1`。



## 总结



该算法通过二分查找高效地确定在给定条件下的最大最小距离，适合大规模数据的处理，时间复杂度为 `O(N log L)`。