有一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以
及周围位置(上边、下边、左边、右边)的灯都会改变一次。即,如果灯原来是点亮的,就会被熄灭;如果灯原来是熄
灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯
的状态。
在上图中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每盏灯设置一个初始状
态。请你按按钮,直至每一盏等都熄灭。与一盏灯毗邻的多个按钮被按下时,一个操作会抵消另一次操作的结果。在下
图中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不改变。
请你写一个程序,确定需要按下
哪些按钮,恰好使得所有的灯都熄灭。根据上面的规则,我们知道1)第2次按下同一个按钮时,将抵消第1次按下时
所产生的结果。因此,每个按钮最多只需要按下一次;2)各个按钮被按下的顺序对最终的结果没有影响;3)对第1行
中每盏点亮的灯,按下第2行对应的按钮,就可以熄灭第1行的全部灯。如此重复下去,可以熄灭第1、2、3、4行的
全部灯。同样,按下第1、2、3、4、5列的按钮,可以熄灭前5列的灯。
输入
5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个空格隔开。0表示灯的初始状态是熄灭的,1表
示灯的初始状态是点亮的。
输出
5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个空格隔开。其中的1表示需要把对应的按钮按下,
0则表示不需要按对应的按钮。
样例输入
0 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0
样例输出
1 0 1 0 0 1 1 1 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0
来源1222
两种思路:
1): 枚举所有的情况:
如:00000 00000
00000 00000
00000 00000
00000 00000
00000 00001...
一个一个的检验。这里有一个小技巧,考虑每种情况时,一排一排的生成方案并立即检验(回溯)
代码(WA):
1 #include "stdafx.h" 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 int set[20][10], temp[20][10], fub[20][10], way[20][10]; 9 void print() 10 { 11 for (int i = 1; i <= 5; i++) 12 { 13 for (int j = 1; j <= 6; j++) 14 cout << way[i][j] << ' '; 15 cout << endl; 16 } 17 } 18 void copy(int k,bool r) 19 { 20 if(r) 21 for (int i = k; i <= k + 2; i++) 22 for (int j = 1; j <= 6; j++) 23 { 24 fub[i][j] = temp[i][j]; 25 } 26 else 27 for (int i = k; i <= k + 2; i++) 28 for (int j = 1; j <= 6; j++) 29 { 30 temp[i][j] = fub[i][j]; 31 } 32 } 33 void change(int i) 34 { 35 for (int j = 1; j <= 6; j++) 36 { 37 if (way[i][j] == 1) 38 { 39 temp[i][j] = !temp[i][j]; 40 temp[i + 1][j] = !temp[i + 1][j]; 41 temp[i - 1][j] = !temp[i - 1][j]; 42 temp[i][j + 1] = !temp[i][j + 1]; 43 temp[i][j - 1] = !temp[i][j - 1]; 44 } 45 } 46 } 47 bool test(int i) 48 { 49 if (i == 0) return 1; 50 for (int j = 1; j <= 6; j++) 51 if (temp[i][j] != set[i][j]) return 0; 52 return 1; 53 } 54 int fu(int i, int j) 55 { 56 if (j == 7) 57 { 58 i++; j = 1; 59 } 60 if (i >= 2 && j == 1) 61 { 62 if (i <= 6) 63 { 64 copy(i - 2, 1); 65 if (i <= 6) change(i - 1); 66 if (!test(i - 2)) 67 { 68 copy(i - 2, 0); 69 return 0; 70 } 71 } 72 if (i == 6 && test(5) == 1) 73 { 74 print(); 75 return 1; 76 } 77 } 78 if (i <= 5) 79 for (int k = 0; k <= 1; k++) 80 { 81 way[i][j] = k; 82 if (fu(i, j + 1)) return 1; 83 } 84 return 0; 85 } 86 int main() 87 { 88 for (int i = 1; i <= 5; i++) 89 for (int j = 1; j <= 6; j++) 90 cin >> set[i][j]; 91 fu(1, 1); 92 return 0; 93 }
2):
枚举 只第一排的方案 并检验,如:0 0 0 0 0 (方案) 0 1 0 1 0(状态)
==> 0 1 0 1 0
生成下一排方案: 0 1 0 1 0
原理是:第i排第j个登是亮的 则第i+1排第j个登是1,否则是0
最后检验第5排 是否全是0;
代码如下(AC):
1 #include "stdafx.h" 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 int a[10][10], b[10][10], w[10][10]; 8 using namespace std; 9 void doit(int i) 10 { 11 for (int j = 1; j <= 6; j++) 12 if (w[i][j] == 1) 13 { 14 a[i][j] = !a[i][j]; 15 a[i + 1][j] = !a[i + 1][j]; 16 a[i - 1][j] = !a[i - 1][j]; 17 a[i][j + 1] = !a[i][j + 1]; 18 a[i][j - 1] = !a[i][j - 1]; 19 } 20 } 21 void clean() 22 { 23 for (int i = 1; i <= 5; i++) 24 for (int j = 1; j <= 6; j++) 25 { 26 a[i][j] = b[i][j]; 27 } 28 } 29 bool check(int i) 30 { 31 if (i == 6) 32 { 33 for (int j = 1; j <= 6; j++) 34 if (a[5][j] == 1) 35 { 36 clean(); 37 return 0; 38 } 39 return 1; 40 } 41 doit(i); 42 for (int j = 1; j <= 6; j++) 43 { 44 if (a[i][j] == 1) w[i + 1][j] = 1; 45 else w[i + 1][j] = 0; 46 } 47 return check(i + 1); 48 } 49 int main() 50 { 51 for (int i = 1; i <= 5; i++) 52 for (int j = 1; j <= 6; j++) 53 { 54 cin >> b[i][j]; 55 a[i][j] = b[i][j]; 56 } 57 for (w[1][1] = 0; w[1][1]<= 1; w[1][1]++) 58 for (w[1][2] = 0; w[1][2] <= 1; w[1][2]++) 59 for (w[1][3] = 0; w[1][3] <= 1; w[1][3]++) 60 for (w[1][4] = 0; w[1][4] <= 1; w[1][4]++) 61 for (w[1][5] = 0; w[1][5] <= 1; w[1][5]++) 62 for (w[1][6] = 0; w[1][6] <= 1; w[1][6]++) 63 { 64 if (check(1)) 65 { 66 for (int i = 1; i <= 5; i++) 67 { 68 for (int j = 1; j <= 6; j++) 69 cout << w[i][j] << ' '; 70 cout << endl; 71 } 72 return 0; 73 } 74 } 75 }