Codeforces Round #615 (Div. 3) E. Obtain a Permutation
Posted meanttobe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #615 (Div. 3) E. Obtain a Permutation相关的知识,希望对你有一定的参考价值。
E. Obtain a Permutation
原题链接:https://codeforces.com/contest/1294/problem/E
题目大意:
给一个无序矩阵,可以进行两个操作:
1.改变任何元素的大小;
2.将任何一列中的元素向上提一位,也就是$a_{1, j}:=a_{2, j}, a_{2, j}:=a_{3, j}, dots, a_{n, j}:=a_{1, j}$
使得最后的矩阵变为有序的序列,即$left.a_{1,1}=1, a_{1,2}=2, ldots, a_{1, m}=m, a_{2,1}=m+1, a_{2,2}=m+2, ldots, a_{n, m}=(i-1) cdot m+j ight)$
求最少的操作次数。
解题思路:
可知,每一列都是独立操作,所以可以计算每一列的最少操作数,首先开一个数组记录vis,以该列的第i行为起点所需进行的操作数。首先初始化为n+i(i从0开始)。然后遍历该列每一行算出如果这一行的数字属于该列,那么是以谁为起点才能使这个位置是它。计算得出答案为第a行,则vis[a]-1,然后计算到到最后一行,最后取最小值。在计算出每列最小值相加可得出最后答案。
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N=2e5+7;
5 vector<int>arr[N];
6 int vis[N];
7 int MAX,MIN;
8 int main(){
9 int n,m,a,ans,idx;
10 cin>>n>>m;
11 for(int i=1;i<=n;i++){
12 arr[i].push_back(0);
13 for(int j=1;j<=m;j++){
14 cin>>a;
15 arr[i].push_back(a);
16 }
17 }
18 ans=0;
19 for(int j=1;j<=m;j++){
20 for(int i=0;i<n;i++){
21 vis[i]=n+i;
22 }
23 for(int i=1;i<=n;i++){
24 if(arr[i][j]<=(j+m*(n-1))&&(arr[i][j]%m==j||(j==m&&arr[i][j]%m==0))){
25 idx=i-arr[i][j]/m-1;
26 if(j==m){
27 idx++;
28 }
29 idx=(idx+n)%n;
30 vis[idx]--;
31 }
32 }
33 MIN=1e9+7;
34 for(int i=0;i<n;i++){
35 MIN=min(MIN,vis[i]);
36 }
37 ans+=MIN;
38 }
39 cout<<ans<<endl;
40 return 0;
41 }
以上是关于Codeforces Round #615 (Div. 3) E. Obtain a Permutation的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #615(Div.3)解题报告
Codeforces Round #615 (Div. 3)
Codeforces Round #615 (Div. 3)
Codeforces Round #615 (Div. 3)