TopCoder Problem: CaptureThemAll
Autor: animeworld | Publicado: 2013-04-21T09:00:00-07:00


#outer-wrapper { margin: 0px; margin-left: 100px; }
#content-wrapper { width: 1000px; }
#main-wrapper { width: 600px;}

Go here to read the problem statement:

http://community.topcoder.com/stat?c=problem_statement&amp;pm=2915&amp;rd=5853

After trying hard and use Eclipse debug help, I could came with a solution! =)


package srm207.round1;

import java.util.LinkedList;

public class CaptureThemAll
{
 public static void main(String[] args) {
  new CaptureThemAll().solve();
 }
 
 public void solve()
 {
  fastKnight("a1", "b3", "c5");
  fastKnight("b1", "c3", "a3");
  fastKnight("a1", "a2", "b2");
  fastKnight("a5", "b7", "e4");
  fastKnight("h8", "e2", "d2");
 }
 
 public int fastKnight(String knight, String rook, String queen)
 {
  int[] k = strToIntArray(knight);
  int[] r = strToIntArray(rook);
  int[] q = strToIntArray(queen);
  
  int min1 = min(k, r) + min(r, q);
  int min2 = min(k, q) + min(q, r);
  
  int min = (min1 &lt; min2) ? min1 : min2;
  
  System.out.println(min);
  
  return min;
 }
 
 public int min(int[] from, int[] to)
 {
  int min = 0;
  LinkedList ks = new LinkedList&lt;&gt;();
  ks.add(from);
  int[][] visited = new int[64][2];
  int[] levelMin = new int[100];
  levelMin[0] = 1;
  int levelMinIdx = 0;
  int lastIndex = -1;
  int jumpidx = 0;
  
  while(!ks.isEmpty())
  {
   if(lastIndex != levelMinIdx) {
    min++;
    lastIndex = levelMinIdx;
   }
   from = ks.poll();
   levelMin[levelMinIdx]--;
   if(levelMin[levelMinIdx] == 0) {
    levelMinIdx++;
   }
   visited = addToVisited(from, visited);
   int[][] jumps = whereKnightCanGo(from);
   jumps = checkVisited(jumps, visited);   
   
   // check if it reached destination
   for(int i = 0; i &lt; jumps.length; i++)
    if(jumps[i][0] == to[0] &amp;&amp; jumps[i][1] == to[1])
     return min;
 
   levelMin[++jumpidx] = jumps.length;
   for(int i = 0; i &lt; jumps.length; i++) {
    int[] k = {jumps[i][0], jumps[i][1]};
    ks.add(k);
   }
  }
  
  return min;
 }
 
 private int[][] addToVisited(int[] from, int[][] visited) {
  for(int i = 0; i &lt; visited.length; i++) {
   if(visited[i][0] == 0) {    
    visited[i][0] = from[0];
    visited[i][1] = from[1];
    break;
   }
  }
  return visited;
 }

 private int[][] checkVisited(int[][] jumps, int[][] visited) {
  int len = jumps.length;
  int[][] temp = new int[len][2];
  j:for(int i = 0, t = 0; i &lt; jumps.length; i++) {
   for(int v = 0; v &lt; visited.length; v++) {
    if(jumps[i][0] == visited[v][0] &amp;&amp; jumps[i][1] == visited[v][1]) {
     len--;
     continue j;
    }    
   }
   temp[t][0] = jumps[i][0];
   temp[t][1] = jumps[i][1];
   t++;
  }
  if(len == jumps.length) return jumps;
  
  int[][] ret = new int[len][2];
  for(int i = 0; i &lt; len; i++) {
   ret[i][0] = temp[i][0]; ret[i][1] = temp[i][1];
  }
  
  return ret;
 }

 public int[][] whereKnightCanGo(int[] k) {
  int len = 8;
  int[][] temp = new int[8][2];
  
  // left bottom
  temp[0][0] = k[0] - 1;
  temp[0][1] = k[1] - 2;
  temp[1][0] = k[0] - 2;
  temp[1][1] = k[1] - 1;
  
  // right bottom
  temp[2][0] = k[0] + 1;
  temp[2][1] = k[1] - 2;
  temp[3][0] = k[0] + 2;
  temp[3][1] = k[1] - 1;
  
  // left top
  temp[4][0] = k[0] - 2;
  temp[4][1] = k[1] + 1;
  temp[5][0] = k[0] - 1;
  temp[5][1] = k[1] + 2;
  
  // right top
  temp[6][0] = k[0] + 1;
  temp[6][1] = k[1] + 2;
  temp[7][0] = k[0] + 2;
  temp[7][1] = k[1] + 1;
  
  
  for(int i = 0; i &lt; 8; i++)
   if(temp[i][0] &lt; 1 || temp[i][1] &lt; 1) len--;
   
  int[][] ret = new int[len][2];
  for(int i = 0, r = 0; i &lt; 8; i++)
   if(temp[i][0] &gt; 0 &amp;&amp; temp[i][1] &gt; 0) {
    ret[r][0] = temp[i][0];
    ret[r][1] = temp[i][1];
    r++;
   }
  
  return ret;
 }
 
 /**
 *  (int)'a' -&gt; 97
 *  (int)'1' -&gt; 49
 */
 public int[] strToIntArray(String s) {
  char[] temp = s.toCharArray();
  return new int[]{(int)temp[0]-96, (int)temp[1]-48};
 }
}