Approach
Breadth-first search
For CCC 2006 S5 - Origin of Life, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 292 lines of Java from the credited upstream file ccc06s5.java.
- The implementation visibly relies on sequence storage, work queue.
- 15 loop blocks detected.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123456789101112131415161718192021222324252627282930313233343536373839 40import java.awt.*;41import hsa.*;42 43public class CCC2006s5OriginofLife44{45 static Console console;46 static int m, n, a, b, c, size;47 static Queue[] x;48 static byte[] [] life1, life2;49 50 public static void main (String[] args)51 {52 console = new Console ();53 TextInputFile f = new TextInputFile ("s5.1.in");54 String s;55 int original;56 57 58 m = f.readInt ();59 n = f.readInt ();60 a = f.readInt ();61 b = f.readInt ();62 c = f.readInt ();63 life1 = new byte [m + 2] [n + 2];64 life2 = new byte [m + 2] [n + 2];65 size = (int) Math.pow (2, m * n);66 x = new Queue [size];67 for (int i = 0 ; i < size ; i++)68 x [i] = new Queue ();69 70 71 for (int i = 0 ; i < m + 2 ; i++)72 for (int j = 0 ; j < n + 2 ; j++)73 {74 life1 [i] [j] = 0;75 life2 [i] [j] = 0;76 }77 for (int i = 1 ; i <= m ; i++)78 {79 s = f.readLine ();80 for (int j = 1 ; j <= n ; j++)81 if (s.charAt (j - 1) == '.')82 life2 [i] [j] = 0;83 else84 life2 [i] [j] = 1;85 }86 original = toInt ();87 fillx ();88 console.println ("" + breadthOrderSearchofX (original));89 }90 91 92 93 94 public static void fillx ()95 {96 for (int i = 0 ; i < size ; i++)97 {98 to2D (i);99 x [nextGen ()].add (i);100 }101 102 }103 104 105 106 107 public static int nextGen ()108 {109 boolean ok = true;110 int up, down, left, right, sum, value;111 for (int i = 1 ; i <= m ; i++)112 for (int j = 1 ; j <= n ; j++)113 {114 up = i - 1;115 down = i + 1;116 left = j - 1;117 right = j + 1;118 sum = life1 [up] [left] + life1 [up] [j] + life1 [up] [right] +119 life1 [i] [left] + life1 [i] [right] +120 life1 [down] [left] + life1 [down] [j] + life1 [down] [right];121 if (life1 [i] [j] == 1)122 if (sum < a || sum > b)123 life2 [i] [j] = 0;124 else125 life2 [i] [j] = 1;126 else127 if (sum > c)128 life2 [i] [j] = 1;129 else130 life2 [i] [j] = 0;131 }132 return toInt ();133 }134 135 136 137 public static int toInt ()138 {139 int out = 0;140 int power = 1;141 for (int i = 1 ; i <= m ; i++)142 for (int j = 1 ; j <= n ; j++)143 {144 out += life2 [i] [j] * power;145 power *= 2;146 }147 return out;148 }149 150 151 152 public static void to2D (int in)153 {154 for (int i = 1 ; i <= m ; i++)155 for (int j = 1 ; j <= n ; j++)156 {157 life1 [i] [j] = (byte) (in % 2);158 in = in / 2;159 }160 }161 162 163 164 165 166 167 public static int breadthOrderSearchofX (int start)168 {169 Queue q1 = new Queue ();170 Queue q2 = new Queue ();171 boolean keepgoing = true;172 int count = 0;173 int k;174 int h;175 q1.add (start);176 while (keepgoing && count < 50)177 {178 while (!q1.empty () && keepgoing)179 {180 h = q1.remove ();181 if (x [h].empty ())182 keepgoing = false;183 else184 {185 x [h].reset ();186 while (!x [h].emptied ())187 {188 k = x [h].getNext ();189 q2.add (k);190 }191 }192 }193 if (keepgoing)194 {195 q1 = q2;196 q2 = new Queue ();197 count++;198 }199 }200 if (count < 50)201 return count;202 else203 return -1;204 }205}206 207class Node208{209 public int data;210 Node next;211 212 public Node (int x)213 {214 data = x;215 next = null;216 }217}218 219class Queue220{221 Node front, back, ptr;222 223 public Queue ()224 {225 front = null;226 ptr = null;227 back = null;228 }229 230 231 public boolean empty ()232 {233 return front == null;234 }235 236 237 public boolean emptied ()238 {239 return ptr == null;240 }241 242 243 244 public void add (int x)245 {246 Node nn = new Node (x);247 if (empty ())248 {249 front = nn;250 ptr = nn;251 }252 else253 back.next = nn;254 back = nn;255 }256 257 258 public int remove ()259 {260 if (empty ())261 return -1;262 else263 {264 int hold = front.data;265 front = front.next;266 ptr = front;267 return hold;268 }269 }270 271 272 public int getNext ()273 {274 if (emptied ())275 return -1;276 else277 {278 int hold = ptr.data;279 ptr = ptr.next;280 return hold;281 }282 }283 284 285 public void reset ()286 {287 ptr = front;288 }289}290 291 292