问题描述 农夫约翰建造了一座有 n 间牛舍的小屋,牛舍排在一条直线上,第 i 间牛舍在 xi 的位置,但是约翰的 m 头牛是斗牛,脾气非常暴躁,因此经常相互攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。约翰决定自己给每头牛分配一个隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?

输入格式 第一行用空格分隔的两个整数 n 和 m。第二行为 n 个用空格隔开的整数,表示位置 xi 。 (2 ≤ n ≤ 100000,0 < xi ≤ 1000000000,2 ≤ m ≤ n )

输出格式 输出仅一个整数,表示最大的最小距离值。

输入输出样例 输入数据 1 5 3 1 2 8 4 9 输出数据 1 3

1 条评论

  • @ 2025-12-14 12:34:12

    #include #include #include using namespace std;

    // 验证当前最小距离mid是否能放下m头牛 bool check(const vector& pos, int m, int mid) { int count = 1; // 已放置的牛数,第一个位置先放1头 int last = pos[0]; // 上一头牛的位置 for (int i = 1; i < pos.size(); ++i) { if (pos[i] - last >= mid) { count++; last = pos[i]; if (count == m) break; // 提前终止,优化效率 } } return count >= m; }

    int main() { ios::sync_with_stdio(false); // 关闭同步,加速输入输出 cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<int> positions(n);
    for (int i = 0; i < n; ++i) {
        cin >> positions[i];
    }
    
    // 排序牛舍位置(贪心的前提)
    sort(positions.begin(), positions.end());
    
    // 二分边界:最小距离1,最大距离为首尾牛舍差值
    int left = 1;
    int right = positions.back() - positions[0];
    int ans = 0;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;  // 避免溢出(替代(left+right)/2)
        if (check(positions, m, mid)) {
            ans = mid;          // 记录可行解
            left = mid + 1;     // 尝试更大的距离
        } else {
            right = mid - 1;    // 距离太大,尝试更小的
        }
    }
    
    cout << ans << endl;
    return 0;
    

    }

    • 1

    信息

    ID
    1954
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    22
    已通过
    13
    上传者