CF1294E Obtain a Permutation

https://www.luogu.com.cn/problem/CF1294E

按列考虑,先对于列中每个找当哪一个为第一个时,这个恰好摆放正确。

\(a_{i,j}=(i-1)*m+j\),记 \(qwq=(a-j)/m\),则当第一个在 \(i-qwq\),时这个摆放正确,或者考虑 \(qwq=n-x+i,x=n-qwq+i\),然后枚举第一个就好了。

注意判下是否值在这列,不仅仅判是否等差数列当中,还要判是否前 \(n\) 项。

#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
#define ID(X,Y) ((X-1)*m+Y)
const int N=(int)(2e5+5);
int n,m,a[N],ans[N];
signed main() {
	cin.tie(0); ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			cin>>a[ID(i,j)];
		}
	}
	int answ=0;
	for(int i=1;i<=m;i++) {
		for(int j=0;j<=n;j++) ans[j]=0;
		for(int j=1;j<=n;j++) {
			if((a[ID(j,i)]-1)%m!=i-1) continue ;
			int qwq=(a[ID(j,i)]-i)/m;
			if(qwq>=n) continue ;
			if(j-qwq>=1) ++ans[j-qwq];
			if(1<=n+j-qwq&&j<=n+j-qwq&&n+j-qwq<=n) ++ans[n+j-qwq];
		}
		// a=(j-1)*m+i
		// (j-1)=n-x+i
		int res=(int)(2e9);
		for(int j=1;j<=n;j++) {
			res=min(res,j-1+n-ans[j]);
		}
//		cout<<res<<'\n';
		answ+=res;
	}
	cout<<answ;
	return 0;
}


posted @ 2022-07-13 16:29  FxorG  阅读(19)  评论(0编辑  收藏  举报