一、思路
采用位图来存储棋盘的状态,每个格子的黑白颜色用0和1来表示,则整个棋盘可以用一个16位的整数来表示,采用广度优先枚举,每次翻一个格子,同时用一个大数组标记到达每一个状态的次数,每次翻转会产生一个新的状态,如果状态在之前出现过,即大数组中对应的不是0,则不放入队列中,如果在队列为空时还没有找到,则说明无解。
采用位图来存储棋盘的状态,每个格子的黑白颜色用0和1来表示,则整个棋盘可以用一个16位的整数来表示,采用广度优先枚举,每次翻一个格子,同时用一个大数组标记到达每一个状态的次数,每次翻转会产生一个新的状态,如果状态在之前出现过,即大数组中对应的不是0,则不放入队列中,如果在队列为空时还没有找到,则说明无解。
二、代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int state = readData(scan);
int min = bfs(state);
if (min == -1) {
System.out.println("Impossible");
} else {
System.out.println(min);
}
}
public static int readData(Scanner scan) {
int state = 0;
for (int i = 0; i < 4; i++) {
String line = scan.nextLine();
for (int j = 0; j < line.length(); j++) {
if (line.charAt(j) == 'w') {
state = (state << 1) & (~0x01);
} else if (line.charAt(j) == 'b') {
state = (state << 1) | 0x01;
}
}
}
return state;
}
public static int bfs(int state) {
if (state == 0 || state == 65535) {
return 0;
}
int[] count = new int[65536];
Queue<Integer> queue = new LinkedList<Integer>();
count[state] = 1;
queue.add(state);
int current_state;
while (!queue.isEmpty()) {
current_state = queue.poll();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int next_state = flip(current_state, i, j);
if (next_state == 0 || next_state == 65535) {
return count[current_state];
} else {
if (count[next_state] == 0) {
count[next_state] += count[current_state] + 1;
queue.add(next_state);
}
}
}
}
}
return -1;
}
private static int flip(int state, int x, int y) {
int t;
t = change(state, x, y);
if (t != -1) {
state = t;
}
t = change(state, x - 1, y);
if (t != -1) {
state = t;
}
t = change(state, x + 1, y);
if (t != -1) {
state = t;
}
t = change(state, x, y - 1);
if (t != -1) {
state = t;
}
t = change(state, x, y + 1);
if (t != -1) {
state = t;
}
return state;
}
private static int change(int state, int x, int y) {
if (x < 0 || x >= 4 || y < 0 || y >= 4) {
return -1;
}
int index = 4 * x + y;
int flag = 0x01 << (15 - index);
state = state ^ flag;
return state;
}
}