题目
你玩过“拉灯”游戏吗?
2525 盏灯排成一个 5×55×5 的方形。
每一个灯都有一个开关,游戏者可以改变它的状态。
每一步,游戏者可以改变某一个灯的状态。
游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
我们用数字 11 表示一盏开着的灯,用数字 00 表示关着的灯。
下面这种状态
1 2 3 4 5
| 10111 01101 10111 10000 11011
|
在改变了最左上角的灯的状态后将变成:
1 2 3 4 5
| 01111 11101 10111 10000 11011
|
再改变它正中间的灯后状态将变成:
1 2 3 4 5
| 01111 11001 11001 10100 11011
|
给定一些游戏的初始状态,编写程序判断游戏者是否可能在 66
步以内使所有的灯都变亮。
输入格式
第一行输入正整数 n�,代表数据中共有 n� 个待解决的游戏初始状态。
以下若干行数据分为 n� 组,每组数据有 55 行,每行 55 个字符。
每组数据描述了一个游戏的初始状态。
各组数据间用一个空行分隔。
输出格式
一共输出 n� 行数据,每行有一个小于等于 66
的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。
对于某一个游戏初始状态,若 66 步以内无法使所有灯变亮,则输出
−1−1。
数据范围
0<n≤5000<�≤500
输入样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 3 00111 01011 10001 11010 11100
11101 11101 11110 11111 11111
01111 11111 11111 11111 11111
|
输出样例:
分析
本题关键在于如何枚举
每一行灯的情况由上一行决定,上一行的暗灯由下一行的开关点亮,点亮之后就要改变对应的上下左右其他灯
枚举的是第一行开关闭合与否的情况,与灯的亮暗无关,每一个开关有亮和暗两种情况,5个开关就\(2^5
=32\)种情况,当开关的情况定下来后,第一行的灯的亮暗也就确定了,之后几行的灯的亮暗也跟着确定
举例说明
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import java.util.Arrays; import java.util.Scanner; public class Main { static char[][] matrix = new char[5][]; static char[][] backUp = new char[5][]; static void readMatrix(Scanner scan) { String tmp = scan.nextLine(); for(int i = 0; i < 5; i++) { matrix[i] = scan.nextLine().toCharArray(); backUp[i] = Arrays.copyOf(matrix[i], matrix[i].length); } } static void flip(int x, int y) { if(matrix[x][y] == '0') { matrix[x][y] = '1'; } else { matrix[x][y] = '0'; } } static void changeMatrix(int x, int y) { if(x - 1 >= 0) flip(x - 1, y); if(y - 1 >= 0) flip(x, y - 1); if(y + 1 <= 4) flip(x, y + 1); if(x + 1 <= 4) flip(x + 1, y); flip(x, y); } public static void main(String[] args) { Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int count = 0; for(int i = 0; i < n; i++) { readMatrix(scan);
int minChange = Integer.MAX_VALUE; for(int j = 0; j < 32; j++) { count = 0; String tmpString = String.format("%5s", Integer.toBinaryString(j)).replace(' ', '0');
for(int k = 0; k < 5; k++) { if(tmpString.charAt(k) == '1') { changeMatrix(0, k);
count++; } }
for(int a = 0; a < 4; a++) { for(int b = 0; b < 5; b++) { if(matrix[a][b] == '0') { changeMatrix(a + 1, b); count++; } }
} boolean flag = true; for(int k = 0; k < 5; k++) { if(matrix[4][k] == '0') { flag = false; break; } } if(flag) { minChange = Math.min(count, minChange); } for(int a = 0; a < 5; a++) { matrix[a] = Arrays.copyOf(backUp[a], backUp[a].length); }
} if(minChange <= 6) System.out.println(minChange); else System.out.println(-1); } } }
|
注:
深拷贝与浅拷贝,一个大坑,当时折腾了半天