CF1650E Rescheduling the Exam

CF1650E

原题链接 ←CLick it

题目大意:有一段\(0\)\(d\)的数轴\((d < 1e9)\),有\(n\)个点\((n < 1e5)\),第\(i\)个点的坐标为\(a_i\)\(a_i\)单调递增且不等),定义第\(i\)个点的值为\(a[i] - a[i - 1] - 1\)\(a[0] = 0\)),现在你可以改变一次第\(i\)个点的在数轴上的位置,问经过这样的操作后所有点的值的最小值可能的最大值。

解题思路:考虑改变值最小的点和它前面的一个点,因为如果这个点的值存在,那么得到的结果一定是这个点的值。改变这个点,就让这个点和后面一个点的值合并,从而增大这个点的值;改变这个点前面的一个点,就是让这个点和前面一个点的值合并,从而增大这个点的值。考虑这个点插入的位置,其一是最大值的中间,其二是\(d\)的位置,我们可以取这两个位置的最大值。

参考代码:

int n, d;
int cal(vector<int> &b) {
    int mi = INF, mx = 0;
    for(int i = 1; i < b.size(); i ++) {
        mx = max(mx, b[i] - b[i - 1] - 1);
        mi = min(mi, b[i] - b[i - 1] - 1);
    }
    return min(mi, max(d - b[b.size() - 1] - 1, (mx - 1) >> 1));
}
void solve() {
    cin >> n >> d;
    vector<int> a(n + 1); 
    int min_idx, res = INF;
    for(int i = 1; i <= n;i ++) {
        cin >> a[i];
        if(a[i] - a[i - 1] - 1 < res)  {
            res = a[i] - a[i - 1] - 1;
            min_idx = i;
        }
    }
    vector<int> b;
    for(int i = 0; i <= n; i ++) {
        if(i != min_idx) {
            b.push_back(a[i]);
        }
    }
    res = max(res, cal(b));
    if(min_idx > 1) {
        min_idx --;
        b[min_idx] = a[min_idx + 1];
        res = max(res, cal(b));
    }
    cout << res << '\n';
}

posted @ 2022-03-11 14:09  Muly  阅读(64)  评论(0)    收藏  举报