有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;
}