Obtain a Permutation(思维)

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
3 3
3 2 1
1 2 3
4 5 6
Output
6
Input
4 3
1 2 3
4 5 6
7 8 9
10 11 12
Output
0
Input
3 4
1 6 3 4
5 10 7 8
9 2 11 12
Output
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.
又是一个看着挺简单的题目做了很久。
一开始就是类似于暴力做的,结果错了很多次。。
一开始思路的一个误区,我认为执行操作2的一定是一段连续的数字,就像1 4 7这样的,但是这怎么可能呢?有可能两个数字都要移动那么多的位置,但是他们之间的数字不是这样的,这就要贪心取最优了。
这道题目,每一列是独立的,所以我们应该每一列单独去考虑。对于每一列中的,如果可以移动相同的次数,我们应该归并到一起来计算,这样就可以统计出移动次数0~n-1之间各有多少个数字。每一列这样贪心取最优,就可以了。
代码如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 2e6;
using namespace std;

const int maxx=2e5+100;
vector<int> p[maxx];
int a[maxx];
int n,m;

int main()
{
	scanf("%d%d",&n,&m);
	int x;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		scanf("%d",&x);
		p[i].push_back(x); 
	}
	int ans=0;
	for(int j=0;j<m;j++)
	{
		for(int i=0;i<n;i++) a[i]=0;
		for(int i=1;i<=n;i++)
		{
			if(p[i][j]<=n*m&&(p[i][j]-1)%m==j)
			{
				int tt=p[i][j]/m+(p[i][j]%m?1:0);
				a[(i+n-tt)%n]++;
				//cout<<(i+n-tt)%n<<endl;
			}
		}
		int _min=inf;
		for(int i=0;i<n;i++) _min=min(_min,n-a[i]+i);
		ans+=_min;
	}
	cout<<ans<<endl;
}

努力加油a啊,(o)/~

发布了414 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/104156677