USACO The Castle
1. 对castle进行着色,记录最大的房间大小,并记录所有的房间大小
2. 从下到上,从左到右,每个块的查看,如果上或左侧与当前点着色不一致,假设将其推到,与最大值比较并记录最大值。
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileReader; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 import java.io.PrintWriter; 7 import java.util.Stack; 8 import java.util.StringTokenizer; 9 10 public class castle { 11 /** 12 * return wall status 13 * 14 * @param wcode 15 * @return wall status 0:W , 1:N , 2:E , 3:S 16 */ 17 static boolean[] wall(int wcode) { 18 boolean[] r = new boolean[4]; 19 int a = wcode; 20 if (a >= 8) { 21 a -= 8; 22 r[3] = true; 23 } 24 if (a >= 4) { 25 a -= 4; 26 r[2] = true; 27 } 28 if (a >= 2) { 29 a -= 2; 30 r[1] = true; 31 } 32 if (a == 1) { 33 r[0] = true; 34 } 35 return r; 36 } 37 38 /** 39 * colour the cplan 40 * 41 * @param cplan 42 * color_plan 43 * @param plan 44 * plan 45 * @param roomsize 46 * each color size 47 * @return maxsize of room 48 * 49 */ 50 static int colour(int[][] cplan, int[][] plan, int[] roomsize) { 51 int maxsize = 0; 52 Stack<int[]> stack = new Stack<int[]>(); 53 int cc = 1; 54 int size = 0; 55 56 for (int i = 0; i < plan.length; i++) { 57 for (int j = 0; j < plan[i].length; j++) { 58 if (cplan[i][j] == 0) { 59 stack.push(new int[] { i, j }); 60 size = 0; 61 while (!stack.isEmpty()) { 62 int[] pos = stack.pop(); 63 int x = pos[0]; 64 int y = pos[1]; 65 boolean[] wstatus = wall(plan[x][y]); 66 cplan[x][y] = cc; 67 size++; 68 69 // look around 70 if (!wstatus[2] && y + 1 < plan[i].length && cplan[x][y + 1] == 0) { 71 stack.push(new int[] { x, y + 1 }); 72 cplan[x][y + 1] = cc; 73 } 74 if (!wstatus[1] && x - 1 >= 0 && cplan[x - 1][y] == 0) { 75 stack.push(new int[] { x - 1, y }); 76 cplan[x - 1][y] = cc; 77 } 78 if (!wstatus[0] && y - 1 >= 0 && cplan[x][y - 1] == 0) { 79 stack.push(new int[] { x, y - 1 }); 80 cplan[x][y - 1] = cc; 81 } 82 if (!wstatus[3] && x + 1 < plan.length && cplan[x + 1][y] == 0) { 83 stack.push(new int[] { x + 1, y }); 84 cplan[x + 1][y] = cc; 85 } 86 } 87 if (size > maxsize) { 88 maxsize = size; 89 } 90 roomsize[cc] = size; 91 cc++; 92 } 93 } 94 } 95 roomsize[0] = cc - 1; 96 return maxsize; 97 } 98 99 /** 100 * most valuable to push 101 * 102 * @param pos 103 * x,y,0|1(N|E) 104 * @param cplan 105 * 106 * @param roomsize 107 * each color size 108 * @return maxsize after push 109 */ 110 static int pushwall(int[] pos, int[][] cplan, int[] roomsize) { 111 int maxsize = 0; 112 for (int j = 0; j < cplan[0].length; j++) { 113 for (int i = cplan.length - 1; i >= 0; i--) { 114 // N 115 if (i - 1 >= 0 && cplan[i][j] != cplan[i - 1][j]) { 116 if (roomsize[cplan[i - 1][j]] + roomsize[cplan[i][j]] > maxsize) { 117 maxsize = roomsize[cplan[i - 1][j]] + roomsize[cplan[i][j]]; 118 pos[0] = i; 119 pos[1] = j; 120 pos[2] = 0; 121 } 122 } 123 if (j + 1 < cplan[0].length && cplan[i][j + 1] != cplan[i][j]) { 124 if (roomsize[cplan[i][j + 1]] + roomsize[cplan[i][j]] > maxsize) { 125 maxsize = roomsize[cplan[i][j + 1]] + roomsize[cplan[i][j]]; 126 pos[0] = i; 127 pos[1] = j; 128 pos[2] = 1; 129 } 130 } 131 132 } 133 } 134 return maxsize; 135 } 136 137 /** 138 * 139 * @param out 140 * @param plan 141 */ 142 static void calc(PrintWriter out, int[][] plan) { 143 int maxsize = 0; 144 int roomcount = 0; 145 int maxsize_push = 0; 146 int[] pos_to_push = new int[3]; // 0:x 1:y 2:direction(0:N,1:W) 147 int[][] color_plan = new int[plan.length][plan[0].length]; 148 int[] roomsize = new int[plan.length * plan[0].length + 1]; 149 150 maxsize = colour(color_plan, plan, roomsize); 151 152 roomcount = roomsize[0]; 153 154 maxsize_push = pushwall(pos_to_push, color_plan, roomsize); 155 156 out.println(roomcount); 157 out.println(maxsize); 158 out.println(maxsize_push); 159 out.println((pos_to_push[0] + 1) + " " + (pos_to_push[1] + 1) + " " + (pos_to_push[2] == 0 ? 'N' : 'E')); 160 // System.out.println(maxsize); 161 // for (int i = 1; i < roomsize.length; i++) { 162 // System.out.print(roomsize[i] + " "); 163 // } 164 // System.out.println(); 165 // System.out.println(); 166 // System.out.println(); 167 // for (int i = 0; i < color_plan.length; i++) { 168 // String tmp = ""; 169 // for (int j = 0; j < color_plan[i].length; j++) { 170 // tmp += color_plan[i][j] + " "; 171 // } 172 // System.out.println(tmp); 173 // } 174 } 175 176 /** 177 * @param args 178 * @throws IOException 179 */ 180 public static void main(String[] args) throws IOException { 181 // Use BufferedReader rather than RandomAccessFile; it's much faster 182 BufferedReader f = new BufferedReader(new FileReader("castle.in")); 183 // input file name goes above 184 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("castle.out"))); 185 // Use StringTokenizer vs. readLine/split -- lots faster 186 StringTokenizer st = new StringTokenizer(f.readLine()); 187 int m, n; 188 m = Integer.parseInt(st.nextToken()); 189 n = Integer.parseInt(st.nextToken()); 190 191 int[][] plan = new int[n][m]; 192 193 for (int i = 0; i < n; i++) { 194 st = new StringTokenizer(f.readLine()); 195 for (int j = 0; j < m; j++) { 196 plan[i][j] = Integer.parseInt(st.nextToken()); 197 } 198 } 199 200 calc(out, plan); 201 202 out.close(); // close the output file 203 System.exit(0); // don't omit this! 204 205 } 206 }