题目大意:有一个5*6的灯组,按一盏灯会让其他上下左右4栈和他自己灯变为原来相反的状态,要怎么按才会把所有的灯都按灭?
3279翻版题目,不多说,另外这一题还可以用其他方法,比如DFS,BFS,不过这些都挺慢的,月还有一个特别厉害的方法,高斯消元法,等我以后再来写
1 #include <iostream> 2 #include <algorithm> 3 #include <functional> 4 5 using namespace std; 6 7 static int map[5][6], store[5][6], flip[5][6]; 8 static int dirx[4] = { -1, 0, 0, 1 }; 9 static int diry[4] = { 0, -1, 0, 0 }; 10 11 int solve(void); 12 int get_light(const int, const int); 13 14 int main(void) 15 { 16 int sum_of_martrix, ans, res; 17 scanf("%d", &sum_of_martrix); 18 19 for (int k = 1; k <= sum_of_martrix;k++) 20 { 21 ans = INT_MAX; 22 for (int i = 0; i < 5; i++)//Read Gragh 23 for (int j = 0; j < 6; j++) 24 scanf("%d", &map[i][j]); 25 26 for (int i = 0; i < 1 << 6; i++) 27 { 28 memset(flip, 0, sizeof(flip)); 29 for (int j = 0; j < 6; j++) 30 flip[0][5 - j] = (i >> j) & 1; 31 res = solve(); 32 if (res < ans) 33 { 34 ans = res; 35 memcpy(store, flip, sizeof(flip)); 36 } 37 } 38 printf("PUZZLE #%d ", k); 39 for (int i = 0; i < 5; i++) 40 { 41 for (int j = 0; j < 6; j++) 42 printf("%d ", store[i][j]); 43 printf(" "); 44 } 45 } 46 return EXIT_SUCCESS; 47 } 48 49 int solve(void) 50 { 51 int ans = 0; 52 for (int i = 1; i < 5; i++) 53 for (int j = 0; j < 6; j++) 54 flip[i][j] = get_light(i - 1, j);//如果这一列的上一行是亮灯,那么必须按下这盏灯 55 56 for (int j = 0; j < 6; j++) 57 { 58 if (get_light(4, j) == 1)//看最后一行的灯的情况是否全部灯都灭了 59 return INT_MAX; 60 } 61 62 for (int i = 0; i < 5; i++) 63 for (int j = 0; j < 6; j++) 64 ans += flip[i][j]; 65 return ans; 66 } 67 68 int get_light(const int y, const int x) 69 { 70 int dx, dy, sum = map[y][x]; 71 72 for (int i = 0; i < 4; i++) 73 { 74 dx = x + dirx[i]; dy = y + diry[i]; 75 if (0 <= dx && dx < 6 && 0 <= dy && dy < 5) 76 sum += flip[dy][dx]; 77 } 78 return sum % 2; 79 }