游戏金币阵列

1 篇文章 0 订阅
1 篇文章 0 订阅

有m*n(m<=100,n<=100)个金币在桌面上排成一个m行n 列的金币阵列。每一枚金币或正面朝上或背面朝上。用数字表示金币状态,0表示金币正面朝上,1 表示背面朝上。  

金币阵列游戏的规则是:
(1)每次可将任一行金币翻过来放在原来的位置上;
(2)每次可任选2 列,交换这2 列金币的位置。
编程任务:给定金币阵列的初始状态和目标状态,编程计算按金币游戏规则,将金币阵列从初始状态变换到目标状态所需的最少变换次数。

Input

输入数据有多组数据。第1行有1 个正整数k,表示有k 组数据。每组数据的第1 行有2 个正整数m 和n。以下的m行是金币阵列的初始状态,每行有n 个数字表示该行金币的状态,0 表示金币正面朝上,1 表示背面朝上。接着的m行是金币阵列的目标状态。

Output

将计算出的最少变换次数按照输入数据的次序输出。相应数据无解时输出-1。


#include <iostream>

using namespace std;

void swap(int **Matrix,int rownum,int col1,int col2)//交换第col1和col2列的函数
{
    int k;
    for( k = 0; k < rownum; k++)
    {
        int tmp = 0;
                
        tmp = *(Matrix[k]+col1);
        *(Matrix[k]+col1) = *(Matrix[k]+col2);
        *(Matrix[k]+col2) = tmp;
    }
}

bool isSame(int **SMatrix,int **TMatrix,int rownum,int SMcol,int TMcol)//判断SMatrix的SMcol和TMatrix的TMcol列是否形同
{
    int count = 0;

    for(int k = 0; k < rownum; k++)
    {    
        if( *(SMatrix[k]+SMcol) == *(TMatrix[k]+TMcol) )
            count++;
    }

    if( count == rownum) 
        return true;
    else
        return false;
}

int main()
{
    int caseNum = 0;
    int row,col;
    int pc = 0;

    cin>>caseNum;
    
    int *caseResult = new int [caseNum];
    
    int i;
    for( i = 0; i < caseNum; i++)
        caseResult[i] = 0;
    
    while( pc < caseNum ) 
    {
        cin>>row>>col;

        int **pSorcMatrix = new int* [row];
        int **pTrgtMatrix = new int* [row];
           
            for( int i = 0; i < 2*row; i++)
            {    
                    if( i < row )
                        pSorcMatrix[i] = new int [col];
                    else
                        pTrgtMatrix[i-row] = new int [col];
                    int j;
                    for( j = 0; j < col; j++)
                    {
                        int tt;
                        cin>>tt;

                        if( i < row )
                            *(pSorcMatrix[i]+j) = tt;
                        else 
                            *(pTrgtMatrix[i-row]+j) = tt;
                    }
            }                
        /*
        **先比较每行,如果1的个数相同则不管,如果1的个数和目标的0的个数相同则翻过这一行,如果不是这两种情况则无解 
        **然后比较每列,如果不同则到后面的列中找到相同的列交换这两列,如果找不到相同的了,则无解。
        */
        //核心
        //比较行
        for(int i = 0; i < row; i++)
        {    
                int SMcount1 = 0;
                int SMcount0 = 0;
                int TMcount1 = 0;
                int TMcount0 = 0;
                
                for(int j = 0; j < col; j++)
                {
                    int Stmp = *(pSorcMatrix[i]+j);
                    int Ttmp = *(pTrgtMatrix[i]+j);

                    if( Stmp == 1)    SMcount1++;
                    else if( Stmp == 0)    SMcount0++;

                    if( Ttmp == 1)    TMcount1++;
                    else if( Ttmp == 0)    TMcount0++;
                }
                
                if( SMcount1 == TMcount1 )     continue;

                else if( SMcount1 == TMcount0 )
                        {
                            for( int k = 0; k < col; k++)
                                (*(pSorcMatrix[i]+k) == 1) ? (*(pSorcMatrix[i]+k) = 0) : (*(pSorcMatrix[i]+k) = 1);
                            
                            caseResult[pc] ++;
                        }
                    else{
                        caseResult[pc] = -1;
                        break;
                    } 
        }
        //比较列
        int n;
        for( n = 0; n < col; n++)
        {        
                if( caseResult[pc] == -1 )    break;

                if( isSame(pSorcMatrix,pTrgtMatrix,row,n,n) )
                     continue;

                else{     
                            int countDifCol = 0;
            
                            if( n == col && !isSame(pSorcMatrix,pTrgtMatrix,row,n,n) )    
                            {
                                caseResult[pc] = -1;
                                break;
                            }
                            else{
                                    for(int p = n+1; p < col; p++)
                                    {
                                            if( isSame(pSorcMatrix,pTrgtMatrix,row,p,n) )
                                            {
                                                swap(pSorcMatrix,row,p,n);
                                                caseResult[pc] ++;
                                            }
                                            else{
                                                countDifCol++;
                                            }
                                    }

                                    if( countDifCol == col-n-1)    
                                    {
                                        caseResult[pc] = -1;
                                        break;
                                    }
                                }
                    }
        }

        for (int i = 0; i < row; i++)
        {
            delete [] pSorcMatrix[i];
            delete [] pTrgtMatrix[i];
        }
        delete [] pSorcMatrix;            
        delete [] pTrgtMatrix;

            pc++;
    }    

    for( i = 0; i < caseNum; i++)
        cout<<caseResult[i]<<endl;
    
    delete [] caseResult;

    return  0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值