hiho 1242 MX Loves Game

这题有个特殊的地方,就是每一行数字只有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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值