金币阵列问题
有m*n枚金币在桌面上排成一个金币阵列。
每一个金币正面朝上,或背面朝上,分别用0和1表示。
金币阵列游戏的规则是:
(1)每次可将任一行金币翻过来放在原来的位置上;
(2)每次可任选2列,交换这2列金币的位置。
给定金币的初始状态和目标状态,计算按金币游戏规则,将金币阵列从初始状态变换到目标状态所需的最少变换次数。
#include <stdio.h>
int main()
{
int i,j,k,h,count,flag=1,temp;
int a[4][3]={{1,0,1},{0,0,0},{1,1,0},{1,0,1}};//初始矩阵
int b[4][3]={{1,0,1},{1,1,1},{0,1,1},{1,0,1}};//目标矩阵
// int a[4][3]={{1,0,1},{0,0,0},{1,0,0},{1,1,1}};//初始矩阵
// int b[4][3]={{1,1,0},{1,1,1},{0,1,1},{1,0,1}};//目标矩阵
int c[4][3];//副矩阵
for(i=0;i<3;i++)//i控制列
{
count=0;
if(i>0)//交换两列
{
for(k=0;k<4;k++)//第i列与第0列交换
{
temp=b[k][0];
b[k][0]=b[k][i];
b[k][i]=temp;
}
count++;
}
else
{
for(j=0;j<4;j++)//第0列匹配完成
{
if(a[j][0]!=c[j][0])
{
for(k=0;k<3;k++)
{
b[j][k]++;
if(b[j][k]==2)
b[j][k]=0;
}
count++;
}
}
}
if(i>0){
for(j=i;j<3;j++)//1-n列 到此为止,前i-1列匹配完成
{
for(k=0;k<4;k++)//k控制行数
{
if(a[k][i]!=b[k][j])
{
if(i==2 && j==2)
flag=0;
break;
}
else if(k==3)//k走完,j走完,交换i列与j列 && j==2
{
for(h=0;h<4;h++)
{
temp=b[h][j];
b[h][j]=b[h][i];
b[h][i]=temp;
}
count++;
}
}
}
}
}
if(flag)
printf("最少需要:%d次\n",count);
else
printf("无法完成。\n");
return 0;
}
/*
思路:
因为要求最少变换次数,所以行变换只能变换一次,因此剩下的都是列变换。
a. 第i列与第0列交换,与目标矩阵的第0列匹配(进行行变换),然后依次匹配剩下的列。
b. 如果匹配成功,则交换,继续匹配剩下的列。
c. 如果匹配失败,让第i+1列与第0列交换,在重新进行 a => b => c。
*/