package com.raylew.algorithm.poj; import java.util.LinkedList; import java.util.Scanner; /** * Created by [Ray Lew] on 2015/7/7. * QQ:897929321 * from:poj1753 * algorithm:bfs,enum */ /* Sample Input: b w w b b b w b b w w b b w w w Sample Output: 4 */ public class POJ1753 { boolean[] state = new boolean[65536];//状态 int N = 4; int minimumCount = 0; public static void main(String[] args) { int N = 4; int[][] matrix = new int[N][N]; Scanner scanner = new Scanner(System.in); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { String str = scanner.next(); if (str.equals("b")) { matrix[i][j] = 1; } } } POJ1753 poj1753 = new POJ1753(); poj1753.bfs(matrix); } /** * enum all possible situation */ public void bfs(int[][] matrix) { //init LinkedList<String> list1 = new LinkedList<String>(); state[convertMatrixToNum(matrix)] = true; list1.add(convertMatrixToString(matrix)); LinkedList<String> list2 = new LinkedList<String>(); //start bfs while (true) { if (list1.size() == 0) { if (list2.size() == 0) { System.out.println("Impossible"); break; } minimumCount++; for (String item : list2) { list1.add(item); } list2 = new LinkedList<String>(); } int[][] first_matrix = convertStringToMatrix(list1.removeFirst()); state[convertMatrixToNum(first_matrix)] = true; if (isMatched(first_matrix)) {//matched System.out.println(minimumCount); //display(first_matrix); return; } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int[][] new_matrix = flip(first_matrix, i, j); if (isMatched(new_matrix)) {//matched System.out.println(minimumCount + 1); //display(new_matrix); return; } else { //unmatched int hash = convertMatrixToNum(new_matrix); if (!state[hash]) { String matrixStr = convertMatrixToString(new_matrix); list2.add(matrixStr); } } } } } } /** * flip the matrix at (i,j) * * @param matrix * @param i * @param j */ public int[][] flip(int[][] matrix, int i, int j) { matrix[i][j] = 1 - matrix[i][j];//flip center if (j > 0) {//up matrix[i][j - 1] = 1 - matrix[i][j - 1]; } if (i < (N - 1)) {//right matrix[i + 1][j] = 1 - matrix[i + 1][j]; } if (j < (N - 1)) {//down matrix[i][j + 1] = 1 - matrix[i][j + 1]; } if (i > 0) {//left matrix[i - 1][j] = 1 - matrix[i - 1][j]; } return matrix; } /** * judge whether the new matrix is matched with the expectation * * @param matrix * @return */ public boolean isMatched(int[][] matrix) { int num = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { num += matrix[i][j]; } } return (num == 0 || num == N * N); } /** * convert matrix to a number(exactly hash value) * * @param matrix * @return */ public int convertMatrixToNum(int[][] matrix) { int num = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int radix = N * N - 1 - (i * N + j); num += matrix[i][j] * Math.pow(2, radix); } } return num; } /** * convert matrix to string * * @param matrix * @return */ public String convertMatrixToString(int[][] matrix) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { sb.append(matrix[i][j]); } } return sb.toString(); } /** * convert string to matrix * * @param str * @return */ public int[][] convertStringToMatrix(String str) { int[][] matrix = new int[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int index = i * N + j; matrix[i][j] = Integer.parseInt(str.charAt(index) + ""); } } return matrix; } /** * print matrix to console * * @param matrix */ public void display(int[][] matrix) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); } System.out.println(); } }