E. Obtain a Permutation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a rectangular matrix of size n×mn×m consisting of integers from 11 to 2⋅1052⋅105.
In one move, you can:
- choose any element of the matrix and change its value to any integer between 11 and n⋅mn⋅m, inclusive;
- take any column and shift it one cell up cyclically (see the example of such cyclic shift below).
A cyclic shift is an operation such that you choose some jj (1≤j≤m1≤j≤m) and set a1,j:=a2,j,a2,j:=a3,j,…,an,j:=a1,ja1,j:=a2,j,a2,j:=a3,j,…,an,j:=a1,j simultaneously.
Example of cyclic shift of the first column
You want to perform the minimum number of moves to make this matrix look like this:
In other words, the goal is to obtain the matrix, where a1,1=1,a1,2=2,…,a1,m=m,a2,1=m+1,a2,2=m+2,…,an,m=n⋅ma1,1=1,a1,2=2,…,a1,m=m,a2,1=m+1,a2,2=m+2,…,an,m=n⋅m (i.e. ai,j=(i−1)⋅m+jai,j=(i−1)⋅m+j) with the minimum number of moves performed.
Input
The first line of the input contains two integers nn and mm (1≤n,m≤2⋅105,n⋅m≤2⋅1051≤n,m≤2⋅105,n⋅m≤2⋅105) — the size of the matrix.
The next nn lines contain mm integers each. The number at the line ii and position jj is ai,jai,j (1≤ai,j≤2⋅1051≤ai,j≤2⋅105).
Output
Print one integer — the minimum number of moves required to obtain the matrix, where a1,1=1,a1,2=2,…,a1,m=m,a2,1=m+1,a2,2=m+2,…,an,m=n⋅ma1,1=1,a1,2=2,…,a1,m=m,a2,1=m+1,a2,2=m+2,…,an,m=n⋅m (ai,j=(i−1)m+jai,j=(i−1)m+j).
Examples
input
Copy
3 3
3 2 1
1 2 3
4 5 6
output
Copy
6
input
Copy
4 3
1 2 3
4 5 6
7 8 9
10 11 12
output
Copy
0
input
Copy
3 4
1 6 3 4
5 10 7 8
9 2 11 12
output
Copy
2
Note
In the first example, you can set a1,1:=7,a1,2:=8a1,1:=7,a1,2:=8 and a1,3:=9a1,3:=9 then shift the first, the second and the third columns cyclically, so the answer is 66. It can be shown that you cannot achieve a better answer.
In the second example, the matrix is already good so the answer is 00.
In the third example, it is enough to shift the second column cyclically twice to obtain a good matrix, so the answer is 22.
题意:
给你一个n*m的数字矩阵a[n][m],保证n*m<=2e5,a[i][j]<=2e5
你有两种操作:
1、在一次操作中,将数组中一个元素变成任意一个数
2、在一次操作中,将某一列向上循环移动一位
问最少多少次操作,将数字矩阵变成如下形式:
思路:
考虑对于某一列每个数,计算它应该在这一列的什么位置,这样我们就能计算出它这一列上移几位这个数才能到正确的位置。
对于不能移到正确位置的数,我们只能通过第一种操作强行改变。
最后,计算一下每一列最少需要进行多少次操作,然后累加一下。总体复杂度O(n*m)。
PS:这道题有个巨坑点,没说a[i][j]<=nm,所以边界处理要注意,不然会挂!终!测!(不要问我为什么知道,我只是终测的时候wa on test 85),作为div3的E题来说,并不算难题。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int maxn=2e6+5;
//const double pi=acos(-1.0);
//const double eps=1e-9;
//const ll mo=1e9+7;
int n,m,k,x;
int a[maxn],c[maxn];
int ans,tmp,cnt;
int flag;
int set_id(int i,int j)
{
return (i-1)*m+j;
}
int main()
{
int T,cas=1;
scanf("%d%d",&n,&m);
rep(i,1,n)
rep(j,1,m)
{
int id=set_id(i,j);
scanf("%d",&a[id]);
}
int ans=0;
rep(j,1,m)
{
rep(i,0,n-1) c[i]=0;
int as=n;
rep(i,1,n)
{
int id=set_id(i,j);
if(a[id]%m==j%m)
{
int s=(a[id]-j)/m+1;
if(s<=0||s>n) continue;
int k=(i-s+n)%n;
c[k]++;
}
}
rep(i,0,n-1)
as=min(as,i+n-c[i]);
//cout<<as<<endl;
ans+=as;
}
printf("%d\n",ans);
return 0;
}
来源:CSDN
作者:LSD20164388
链接:https://blog.csdn.net/LSD20164388/article/details/104077052