Codeforces Round #776 (Div. 3) E

E. Rescheduling the Exam

显然我们能想到的每次操作都是先将最小的取出来操作
要是我们有两个数都是最小的 我们只有相邻的时候才能操作
要是大于两个 那我们就不管怎么操作都是寄的 我们直接输出即可

    int cnt=0;
    for(auto i:v)if(i==mnn)cnt++;
    if(cnt>=3){
        cout<<mnn-1<<endl;
        return;
    }

只有一个的时候显然只有对自己和自己前面那个操作才能把最小去掉
我们考虑如何贪心的放置
首先放在一个最长的中间是一种可能解 还有就是直接放在最后 就不用/2

  int mx = v.back();
  for (int j = 0; j < v.size() - 1; j++)
      mx = max(mx, v[j] / 2);

最后注意要恢复现场 然后只能枚举前面n个 ans要减1

void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n+1),v;
    int mnn=INF;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        v.push_back(a[i]-a[i-1]);
        mnn=min(mnn,v.back());
    }
    int cnt=0;
    for(auto i:v)if(i==mnn)cnt++;
    if(cnt>=3){
        cout<<mnn-1<<endl;
        return;
    }
    v.push_back(m-a[n]);
    int ans=0;
    for(int i=0;i<v.size()-1;i++) {
        if(v[i]==mnn||v[i+1]==mnn) {
            v[i + 1] += v[i];
            int mx = v.back();
            for (int j = 0; j < v.size() - 1; j++)
                mx = max(mx, v[j] / 2);
            int mn = INF;
            for (int j = 0; j < v.size() - 1; j++)
                if (j != i)mn = min(mn, v[j]);
            if (mn > mx)ans = max(ans, mx);
            else ans = max(ans, mn);
            v[i + 1] -= v[i];
        }
    }
    cout<<ans-1<<endl;
}
posted @ 2022-11-04 18:13  ycllz  阅读(18)  评论(0)    收藏  举报