• Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts


    Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts


    题意:给一个长度为(n)的排列,每次可以向右循环移位一次,计算(sum_{i=1}^{n}|p_i - i|)的最小值,并求最小值是在第几次移动时取到的。

    思路:我们注意到对于每个(p_i),其位置都取遍了(1-n),那么可以分成(p_i > i) 和 $p_i <= i $两种

    对于前者 每次移动贡献-1,后者贡献+1,而且我们可以容易计算出每次移动后这两者的数量,于是可以模拟(O(n))

    #include<bits/stdc++.h>
    #define P pair<int,int>
    #define LL long long
    using namespace std;
    const int N = 1e6 + 10;
    int n, p[N],cnt[N];
    
    int main(){
        cin>>n;
        for(int i = 1;i <= n;i++) cin>>p[i];
        int L = 0,R = 0;
        LL res = 0,ans;
        for(int i = 1;i <= n;i++){
            res += abs(p[i] - i);
            cnt[(p[i]-i+n)%n]++; ///移动x次变成p[i] <= i的个数
            if(p[i] <= i) R++;
            else L++;
        }
        ans = res;
        int idx = 0;
        for(int k = 1;k < n;k++){
            res -= L; /// 左边的减少一
            res += R - 1; ///右边的增加一,右端点除外
            res += p[(n-k)%n+1] - n + p[(n-k)%n+1] - 1;///处理右端点
            L -= cnt[k] - 1;
            R += cnt[k] - 1;
            if(res < ans){
                idx = k,ans = res;
            }
        }
        cout<<ans<<" "<<idx<<endl;
       return 0;
    }
  • 相关阅读:
    决策树
    结巴分词demo
    线性回归分析波士顿房价
    将python的字典格式数据写入excei表中
    ubuntu16.04电脑重启/关机卡死问题记录
    Hadoop 平台搭建
    Linux 常用命令
    灰度共生矩阵
    图像类型
    linux中的一些常用命令
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/7123766.html
Copyright © 2020-2023  润新知