最近在学习mooc上北大的算法课程,其中有一个熄灯问题的算法,感觉特别精妙,不过本人愚钝,看了3天多,才完全明白其中含义。因为该视频教程是使用C++编写的。本人java程序员一枚,就将程序改造层java版本的了,并且加上了一些调试信息,辅助理解。感觉程序要敲出来,并且debug一下,才能真正明白。为了史大家少走弯路,我本人将源码贡献出来,供大家参考。
import java.util.Scanner;
public class S4 {
static int light[][] = new int[4][5]; //灯亮情况数组5行6列去外围(左右头尾);
static int press[][] = new int[4][5]; //灯亮情况数组5行6列去外围(左右头尾);
public static void main(String[] args) {
System.out.println("请输入灯亮情况");
Scanner input = new Scanner(System.in);
//获取输入数组:灯亮情况
for (int i = 1; i < light.length; i++) { //行
for (int j = 1; j < light[i].length - 1; j++) { //列
light[i][j] = input.nextInt();
}
}
System.out.println("输入完毕");
if (firstRow()) {
for (int i = 1; i < press.length; i++) { //行
for (int j = 1; j < press[i].length - 1; j++) { //列
System.out.print(press[i][j] + " ");
}
System.out.println(); //换行
}
} else {
System.out.println("找不到解法");
}
}
private static boolean firstRow() {
//二进制转换器
for (int i = 0; i < light.length; i++) { //行
for (int j = 0; j < light[i].length; j++) { //列
press[i][j] = 0; //初始化所有按钮为0,包括外围
}
}
while (!guess(press)) {
press[1][1]++;
int c = 1;//指向的数
while (press[1][c] > 1) {
press[1][c] = 0;//进位变0
c++;
press[1][c]++;
if (press[1][press[1].length - 2] > 1) {
return false;
}
}
}
return true;
}
private static boolean guess(int[][] press) {
for (int i = 2; i < press.length; i++) {//行
System.out.println(press[i].length-1);
for (int j = 1; j < press[i].length-1; j++) {
System.out.println("light["+(i-1)+"]["+j+"]:"+light[i - 1][j]);
System.out.println("press["+(i-1)+"]["+j+"]:"+press[i - 1][j]);
System.out.println("press["+(i-1)+"]["+(j-1)+"]:"+press[i - 1][j-1]);
System.out.println("press["+(i-2)+"]["+(j)+"]:"+press[i - 2][j]);
System.out.println("press["+(i-1)+"]["+(j+1)+"]:"+press[i - 1][j + 1]);
System.out.println("总共press["+i+"]["+j+"]:"+((light[i-1][j] + press[i-1][j] + press[i - 1][j - 1] + press[i - 2][j]+press[i-1][j+1]) % 2));
press[i][j] = (light[i-1][j] + press[i-1][j] + press[i - 1][j - 1] + press[i - 2][j]+press[i-1][j+1]) % 2;
}
}
System.out.println(press[press.length-1].length);
int length =press.length - 1;
for (int i = 1; i <= press[press.length-1].length-2; i++) {
System.out.println("press["+length+"]["+i+"]"+press[length][i]);
System.out.println("light["+length+"]["+i+"]"+light[length][i]);
System.out.println("press["+length+"]["+(i-1)+"]"+press[length][i-1]);
System.out.println("press["+length+"]["+(i+1)+"]"+press[length][i+1]);
System.out.println("press["+(length-1)+"]["+i+"]"+press[length-1][i]);
if (press[length][i]!=(light[length][i]+press[length][i-1]+press[length][i+1]+press[length-1][i])%2)
{
return false;
}
}
return true;
}
}
输入
1 1 1
1 1 1
1 1 1
得到
1 0 1
0 1 0
1 0 1