这题有个特殊的地方,就是每一行数字只有1~N,所以这表示行交换不会影响列交换,于是我们可以采取个策略,先拿一行变成一样的,我这里拿第一行和下面2-n行枚举来。行交换成一样以后,在吧2矩阵第一列交换成一样,检测是都相同,相同就更新总的次数是不是比以前更小
#include<iostream>
#include<algorithm>
using namespace std;
int map[305][305];
int aimmap[305][305];
int tempmap[305][305];
int n;
bool check()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (tempmap[i][j] != aimmap[i][j])
{
return false;
}
}
return true;
}
void copy()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
tempmap[i][j]=map[i][j];
}
}
void swaprow(int tempi,int tempj)
{
for (int i = 1; i <= n; i++)
{
int temp = tempmap[i][tempi];
tempmap[i][tempi] = tempmap[i][tempj];
tempmap[i][tempj] = temp;
}
}
void swapcross(int tempi, int tempj)
{
for (int i = 1; i <= n; i++)
{
int temp = tempmap[tempi][i];
tempmap[tempi][i] = tempmap[tempj][i];
tempmap[tempj][i] = temp;
}
}
int checkrow(int tempi,int tempj)
{
int prize = 0;
for (int i = 1; i <= n; i++)
{
if (tempmap[tempi][i] != aimmap[tempj][i])
{
for (int j = 1; j <= n; j++)
{
if (tempmap[tempi][j] == aimmap[tempj][i])
{
swaprow(i, j);
prize++;
break;
}
}
}
}
return prize;
}
int checkcross(int tempi, int tempj)
{
int prize = 0;
for (int i = 1; i <= n; i++)
{
if (tempmap[i][tempi] != aimmap[i][tempj])
{
for (int j = 1; j <= n; j++)
{
if (tempmap[j][tempi] == aimmap[i][tempj])
{
swapcross(i, j);
prize++;
break;
}
}
}
}
return prize;
}
void deal()
{
int total = 0x3f3f3f3f;
for (int i = 1; i <= n; i++)//枚举1和n,2行交换到相同
{
int suma = 0;
int sumb = 0;
copy();
suma=checkrow(1, i);//交换1-n的步数
sumb = checkcross(1, 1);// 把第一列交换成一样的步数
if (check())//如果一样,更新
{
total = min(total, suma + sumb);
}
}
if (total != 0x3f3f3f3f)
printf("%d\n", total);
else
printf("%d\n", -1);
}
int main()
{
while (~scanf("%d", &n))
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n;j++)
{
scanf("%d", &map[i][j]);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
scanf("%d", &aimmap[i][j]);
}
deal();
}
}