金幣陣列問題
有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。
*/