Codeforces 1294E Obtain a Permutation

Topic links:

codeforces 1294E Obtain A Permutation

ideas:

For an array of each column, we considered separately, set the current for the first jcolumn ( jfrom 1the beginning);
for the first inumber (position ifrom 0the beginning), it should be i * m + j, so if a number nis in our target sequence, its location should be (n - j) / m;
traversing our current sequence to calculate this number is in the target sequence, if you calculate the current should move many times to get to it should be in the position;
the establishment of an array rcd[], rcd[i]meaning is moved itimes can make rcd[i]the number of recovery;
iterate rcd[], Norway calculating istep where the total time required, i.e. i + n - rcd[i], the minimum value of all values;
each column calculated minimum value that is the addition result;

Code:

#include<bits/stdc++.h>

using namespace std;

inline int read() {
	int x = 0; char c;
	while(c = getchar(), c < '0' || c > '9');
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}

const int maxn = 2e5 + 5;
vector<int> mat[maxn];
inline int get(vector<int> & now, int & c, int & m) {
	int n = now.size(), ans = 1 << 30;
	vector<int> rcd(n + 1);
	for(int & x : rcd) x = 0;
	for(int i = 0; i < n; i++) {
		int x = now[i] - c, y = x / m;
		if(x % m == 0 && y >= 0 && y <= n - 1) ++rcd[(i - y + n) % n];  // the range of y should be noticed
	}
	for(int i = 0; i < n + 1; i++) ans = min(ans, i + n - rcd[i]);
	return ans;
}

int main() {
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);
#endif	
	int n = read(), m = read();
	for(int i = 0; i < n; i++) {
		mat[i].push_back(0);
		for(int j = 1; j <= m; j++) mat[i].push_back(read());
	}
	int ans = 0;
	for(int j = 1; j <= m; j++) {
		vector<int> now;
		for(int i = 0; i < n; i++) now.push_back(mat[i][j]);
		ans += get(now, j, m);	
	}
	cout << ans;
	return 0;
}
Published 301 original articles · won praise 8 · views 7543

Guess you like

Origin blog.csdn.net/qq_45228537/article/details/104076744