求调(全排列做法)
查看原帖
求调(全排列做法)
911439
Nancy_Cherry楼主2023/12/16 11:29

rt

代码有点长

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e18;
long long a[105][105],b[105][105],c[105],d[105]; // 定义ABCD四个数组,分别来存储A矩阵,B矩阵,第C行,第D列
long long n,m,x,y,ans = MAXN,sum;
int f = 0;
int main() {
	cin.tie();
	cout.tie();// 读优 & 写优
	cin >> n >> m;

	// 读入两个矩阵(不再赘述
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> a[i][j];
		}
	}
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> b[i][j];
		}
	}
	int flag = 0;
	// 判断两个矩阵是否相同
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) {
			if(a[i][j] != b[i][j]) {
				flag = 1;
				break;
			}
		}
	}
	if(flag == 0) {
		cout << 0 ;
		return 0;
	}
	//  开始遍历并全排列
	for(int i = 1; i <= n; i++) c[i] = i;
	while(next_permutation(c + 1,c + 1 + n)) {
		for(int i = 1; i <= m; i++) d[i] = i;
		while(next_permutation(d + 1,d + 1 + m)) {
			sum = 0,f = 1;
			for(int i = 1; i <= n && f == 1; i++)
				for(int j = 1; j <= m && f == 1; j++)
					if(a[c[i]][d[j]] != b[i][j]) f = 0; //   a[c[i]][d[j]]!=b[i][j](c[i]存放的是行的方案,d[j]存的是列的方案),两种方案组成的新坐标就是在这种方案下每个数的新位置
			if(f == 0) continue;
			for(int i = 1; i <= n; i++)
				for(int j = i + 1; j <= n; j++)
					if(c[i] > c[j]) sum ++;
			for(int i = 1; i <= n; i++)
				for(int j = i + 1; j <= n; j++)
					if(d[i] > d[j]) sum ++;
			ans = min(ans,sum);
		}
	}
	if(ans == 1e18) cout << -1;
	else cout << ans;
	return 0;
}
2023/12/16 11:29
加载中...