E - Obtain a Permutation CodeForces - 1294E
描述
给一个 n×mn×m 的矩阵,你想要把它还原成如下的矩阵:
你有两种操作:
- 选择一个数,修改它的值。
- 选择一列,每个元素上移一位,第一行的元素移到第 nn 行。
求还原的最小操作次数。
输入
第一行两个正整数 n,mn,m(1≤n,m≤2×1051≤n,m≤2×105,n×m≤2×105n×m≤2×105)。
接下来是一个 n×mn×m 的矩阵 ai,jai,j(1≤ai,j≤2×1051≤ai,j≤2×105)。
输出
一个数表示答案。
样例
输入1
3 3
3 2 1
1 2 3
4 5 6
输出1
6
输入2
4 3
1 2 3
4 5 6
7 8 9
10 11 12
输出2
0
输入3
3 4
1 6 3 4
5 10 7 8
9 2 11 12
输出3
2
解释
样例1:a1,1←7a1,1←7,a1,2←8a1,2←8,a1,3←9a1,3←9,然后每列上移一次。
样例2:矩阵已经还原。
样例3:上移第 22 列 22 次。
//题目描述来自
题解:
因为每一列之间互不影响,所以我们一列一列的来;
qw[n][m] 为原数组;
ans为答案;s[i] 是当前列移动i步就可以回到原位的个数;
k 为qw[j][i]本应在的行数;flag 为移到原位要上移多少行
(一)要判断qw [ i ] [ j ] 是否属于第j列;
属于时qw [ i ] [ j ] >= j & qw [ i ] [ j ] <= n*m;
并且( qw [ i ] [ j ] - j )%m==0;
(二)可以求出 k=(qw[ i ] [ j ] - j ) / m+1;
(三)flag = ( n + i - k ) % n;
//因为
1. 如果 i≥,移动 i−k 个单位即可;
2. 如果 i<k,那首先把它移到第 1 行需要 i−1 次,然后再移1
次到第 n行,从第 n 行移到第 k 行需要 n − k 次,加起来,就是
i − 1 + 1 + n − k,化简得 n + i - k次
所以统一用 n + i - k 再模 n 就行
(四)s[ n + i - k ]++;
(五)循环求出最小移动方案,mi = min( mi , i + n - s [ i ] (i = 0 ~ n-1 ) ;
(六)ans+=mi;
emmmm, qw [ n ][ m ]存的时候可以用vector,一维数组也行