金币阵列问题

问题描述:
有m´ n(m <= 100,n <= 100)个金币在桌面上排成一个m行n 列的金币阵列。每一枚金
币或正面朝上或背面朝上。用数字表示金币状态,0表示金币正面朝上,1 表示背面朝上。
金币阵列游戏的规则是:
(1)每次可将任一行金币翻过来放在原来的位置上;
(2)每次可任选2 列,交换这2 列金币的位置。
算法设计:
给定金币阵列的初始状态和目标状态,计算按金币游戏规则,将金币阵列从初始状态变
换到目标状态所需的最少变换次数。


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


«结果输出:
相应数据无解时
输出-1。

输入文件示例
2
4 3
1 0 1
0 0 0
1 1 0
1 0 1
1 0 1
1 1 1
0 1 1
1 0 1
4 3
1 0 1
0 0 0
1 0 0
1 1 1
1 1 0
1 1 1
0 1 1
1 0 1

输入文件示例
2
-1

算法思路:

1.穷举初始状态数组第一列交换到目标状态的数组的第k列,根据第一列的匹配
情况就可以知道对应的行是否应该进行变换。
2.然后在行变换确定之后,对余下的n-1列,根据更行的值就行匹配。

View Code
  1 --------------------金币阵列_H----------------------------
  2 #ifndef 金币阵列_H
  3 #define 金币阵列_H
  4 
  5 #include<stdio.h>
  6 #include<iostream>
  7 #include<math.h>
  8 
  9 void rowTransform(int** a,int rows,int columns,int row);
 10 void columnTranform(int** a,int rows,int columns,int column1,int column2);
 11 bool isColumnSame(int** a,int** b,int rows,int columns,int column1,int column2);
 12 int timeNeed(int** a,int** b,int rows,int columns);
 13 
 14 
 15 int timeNeed(int** a,int** b,int rows,int columns)
 16 {
 17     int count = INT_MAX;//变换的次数
 18     int** temp;//暂存初始矩阵
 19     temp = (int**)malloc(rows*sizeof(int*));
 20     for(int i=0;i<rows;i++)
 21         temp[i] = (int*)malloc(columns*sizeof(int));
 22     for(int k=0;k<columns;k++)
 23     {
 24         for(int i=0;i<rows;i++)
 25             for(int j=0;j<columns;j++)
 26                 temp[i][j] = a[i][j];
 27         int need = 0;//该种情况需要变换的次数
 28         columnTranform(temp,rows,columns,0,k);
 29         need++;
 30         //查看第一列的每一行是否相等,如果不想等就进行行变换
 31         for(int j=0;j<rows;j++)
 32         {
 33             if(temp[j][0]!=b[j][0])
 34             {
 35                 rowTransform(temp,rows,columns,j);
 36                 need++;
 37             }
 38         }
 39         bool find;
 40         //检查每列是否满足条件,如果满足则为一种变换的步骤,如果不能则交换
 41         for(int i=0;i<columns;i++)
 42         {
 43             find = false;
 44             if(isColumnSame(temp,b,rows,columns,i,i))
 45             {
 46                 find = true;
 47                 continue;
 48             }
 49             for(int j=i+1;j<columns;j++)
 50             {
 51                 if(isColumnSame(temp,b,rows,columns,j,i))
 52                 {
 53                     if(isColumnSame(temp,b,rows,columns,j,j))
 54                         continue;
 55                     columnTranform(temp,rows,columns,i,j);
 56                     need++;
 57                     find = true;
 58                     break;
 59                 }
 60             }
 61             if(find = false)
 62                 break;
 63         }
 64         if(find&&count>need)
 65             count = need;
 66     }
 67     for(int i=0;i<rows;i++)
 68         free(temp[i]);
 69     free(temp);
 70     if(count==INT_MAX)
 71         return -1;
 72     return count;
 73 }
 74 //指定的行进行变换,取反
 75 void rowTransform(int** a,int rows,int columns,int row)
 76 {
 77     for(int i=0;i<columns;i++)
 78         a[row][i]^=1;
 79 }
 80 //两列交换
 81 void columnTranform(int** a,int rows,int columns,int column1,int column2)
 82 {
 83     int temp;
 84     if(column1==column2)
 85         return;
 86     for(int i=0;i<rows;i++)
 87     {
 88         temp = a[i][column1];
 89         a[i][column1] = a[i][column2];
 90         a[i][column2] = temp;
 91     }
 92 }
 93 //判断两列是否相等
 94 bool isColumnSame(int** a,int** b,int rows,int columns,int column1,int column2)
 95 {
 96     for(int i=0;i<rows;i++)
 97         if(a[i][column1]!=b[i][column2])
 98             return false;
 99     return true;
100 }
101 #endif
102 ——————————main.cpp———————————————
103 int main()
104 {
105     FILE* input = fopen("input.txt","r");
106     FILE* output = fopen("output.txt","w");
107     if(input == NULL||output == NULL)
108     {
109         printf("无该文件或无法创建文件!\n");
110         exit(1);
111     }
112     int **a,**b;
113     int rows = 0,columns = 0;
114     int count;//数据的组数
115     fscanf_s(input,"%d",&count);
116     
117     for(int k=0;k<count;k++)
118     {
119         fscanf_s(input,"%d",&rows);
120         fscanf_s(input,"%d",&columns);
121         a = (int**)malloc(rows*sizeof(int*));
122         b = (int**)malloc(rows*sizeof(int*));
123         for(int i=0;i<rows;i++)
124         {
125             a[i] = (int*)malloc(columns*sizeof(int));
126             b[i] = (int*)malloc(columns*sizeof(int));
127         }
128         for(int i=0;i<rows;i++)
129             for(int j=0;j<columns;j++)
130                 fscanf_s(input,"%d",&(a[i][j]));
131         for(int i=0;i<rows;i++)
132             for(int j=0;j<columns;j++)
133                 fscanf_s(input,"%d",&(b[i][j]));
134         int times;
135         times = timeNeed(a,b,rows,columns);
136         fprintf_s(output,"%d\n",times);
137         fflush(output);
138         for(int i=0;i<rows;i++)
139         {
140             free(a[i]);
141             free(b[i]);
142         }
143         free(a);
144         free(b);
145     }
146     fclose(input);
147     fclose(output);
148     return 0;
149 }

 

posted @ 2012-09-24 16:52  我是杀手不冷  阅读(351)  评论(1)    收藏  举报