// Algorithm: // // read input // First mark all warm squares (called external) // Loop while there is butter left // mark all melting squares // remove all melted butter (check if a hole is uncovered) // increment num hours // // print num hours public class Butter { static int R, C; // recursive method to check if adjacent squares are touching // an external square (Standard floodfill algorithm) static void checkExternal(Square [][] board, int i, int j) { if(!board[i][j].border && !board[i][j].occupied && !board[i][j].external) { board[i][j].external = true; // check all adjacent squares checkExternal(board, i+1, j); checkExternal(board, i-1, j); checkExternal(board, i, j+1); checkExternal(board, i, j-1); } } static void findExposed(Square [][] board) { // For each square, if occupied, check // if 2 adjacent are external for(int i = 2; i < R; i++) for(int j = 2; j < C; j++) { if(board[i][j].occupied) { int total = 0; if(board[i+1][j].external) total++; if(board[i-1][j].external) total++; if(board[i][j+1].external) total++; if(board[i][j-1].external) total++; if(total >= 2) board[i][j].exposed = true; } } } static void melt(Square [][] board) { // For each square, if exposed, check // if 2 adjacent are external for(int i = 2; i < R; i++) for(int j = 2; j < C; j++) if(board[i][j].exposed) { // remove from board. board[i][j].occupied = false; // Mark as external, (including any holes) checkExternal(board, i, j); } } // Debugging method static void print(Square [][] board) { for(int i = 1; i <= R; i++) { int j; for(j = 1; j < C; j++) if(board[i][j].occupied) System.out.print("1 "); else System.out.print("0 "); if(board[i][j].occupied) System.out.print("1"); else System.out.print("0"); System.out.println(); } System.out.println(); } static int count(Square [][] board) { int numOccupied = 0; for(int i = 1; i <= R; i++) for(int j = 1; j <= C; j++) if(board[i][j].occupied) numOccupied++; return numOccupied; } public static void main(String [] args) { R = Console.readInt(); C = Console.readInt(); // Initialise the board Square [][] board = new Square[R + 2][C + 2]; for(int i = 0; i < R + 2; i++) for(int j = 0; j < C + 2; j++) board[i][j] = new Square(); for(int i = 1; i <= R; i++) for(int j = 1; j <= C; j++) board[i][j].border = false; // Now mark in all the squares for(int i = 1; i <= R; i++) for(int j = 1; j <= C; j++) if(Console.readInt() == 1) board[i][j].occupied = true; // Mark all external squares checkExternal(board, 1, 1); int hours = 0; // Keep going as long as there is some butter left while(count(board) > 0) { hours++; // another hour passed. // Now find any exposed squares findExposed(board); // Melt the exposed squares melt(board); } System.out.println(hours); } } class Square { boolean external; boolean border; boolean occupied; boolean exposed; Square() { external = false; border = true; occupied = false; exposed = false;} }