zoukankan      html  css  js  c++  java
  • U

    题解:

    注意每一列与每一列之间互不影响,所以贪心地求出没一列的最小操作值,然后累加起来。

    怎么求没一列的最小值呢?维护一个数组same表示其中same[i]=j表示将该序列向上翻滚i次有j个元素归位,那么会有n-j个没有归位,所以我们要修改他们,一共修改n-j次,所以总计n-j+i次。

    所以每一列的答案为min(n-same[i]+i);关于same的求法。首先每一列的元素的取值范围是j<=arr[i][j]<=n*m,并且arr[i][j]%m==j%m,即每一列的元素值对m取值应该相等。只有这样才是该列的元素。

    对于那些不满足条件的不用考虑。因为无论翻转多少次,都无法使其归位。对于满足条件的,假设当前位置为j,然后其目标位置是pos.那么答案为(j-pos+n)%n即为翻转的次数。pos的取值:(arr[i][j]-j)/m+1;

    所以same[(j-pos+n)%n]++;

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=2E5+7;
    vector<ll >ve[N];
    ll same[N];//元素i向上移动same[j]个可以恢复
    int main()
    {
        ll n,m;
        cin>>n>>m;
        ll c=n*m;
        ll y;
        for(ll i=1;i<=c;i++){
            cin>>y;
            if(i%m==0){
                ve[m].push_back(y);
            }
            else ve[i%m].push_back(y);
        }
        ll sum=0;
        for(ll i=1;i<=m;i++){
            ll c=ve[i].size();
            for(ll j=0;j<c;j++){
                if(ve[i][j]<i||ve[i][j]>n*m) continue ;
                if(ve[i][j]%m==i%m){
                    ll pos=(ve[i][j]-i)/m+1;
                    ll k=(j+1-pos+n)%n;
                    same[k]++;            }
            }
            ll cnt=n;
            for(ll j=0;j<n;j++){
                cnt=min(cnt,j+n-same[j]);
                same[j]=0;
            }
            sum+=cnt;
        }
        cout<<sum<<endl;
        return 0;
    }
  • 相关阅读:
    redis修改密码
    redis配置
    django中日志配置
    django中缓存配置
    navicat批量导入数据
    django添加REST_FRAMEWORK 接口浏览
    django验证码配置与使用
    LUA_OBJECT
    LUA comment
    lua-redis
  • 原文地址:https://www.cnblogs.com/Accepting/p/12238997.html
Copyright © 2011-2022 走看看