• [CF1294E] Obtain a Permutation


    给定一个 (n imes m) 矩阵,其中元素为 (1 o nm) 的一个排列,每次操作可以任选一个元素将它变为任意整数,或者选择一列将其循环移位(向上)一格,求使得矩阵变为标准型的最少操作次数

    Solution

    (a[i][j])(i)(j) 列的数,(c[i][j]) 表示第 (j) 列循环移位 (i) 次后有多少个数已经匹配,则答案为

    [sum_{j=1}^m (min_{i=0}^{n-1} (i+n-c[i][j])) ]

    考虑如何计算 (c),由于每个元素只会对一个 (c[?][?]) 产生贡献,所以我们判断每个元素是否可能被填在当列,如果可能,计算应该被填在的位置,算出坐标差值,然后对对应的 (c[?][?]) 计算贡献就好了

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    int n,m,**a,**c;
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        a=new int* [n+1];
        c=new int* [n+1];
        for(int i=0;i<=n;i++) {
            a[i]=new int[m+1];
            c[i]=new int[m+1];
            for(int j=0;j<=m;j++) c[i][j]=0;
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                cin>>a[i][j];
                if(a[i][j]<j||a[i][j]>n*m||(a[i][j]-j)%m) continue;
                c[((i-(a[i][j]-1)/m-1)%n+n)%n][j]++;
            }
        }
        int ans=0;
        for(int j=1;j<=m;j++) {
            int tmp=1e9;
            for(int i=0;i<n;i++) tmp=min(tmp,i+n-c[i][j]);
            ans+=tmp;
        }
        cout<<ans;
    }
    
    
  • 相关阅读:
    My SqL 常用命令
    RGB颜色查询对照表
    Android 对话框(Dialog)大全
    【转】Android一些知识点汇总
    Google Maps API v2密钥申请
    蓝牙中文API文档
    IOS 电商类app 第一版架构 改进
    ios 开发小记 (四)
    ios 深度复制 copy & mutablecopy
    CCS绘制成的三角形箭头
  • 原文地址:https://www.cnblogs.com/mollnn/p/12591992.html
Copyright © 2020-2023  润新知