2016-07-29 2 views
1

이 문제가 발생하여 어떤 이유로 정확한 결과가 나오지 않습니다. 문자열의 배열을 감안할 때, 문자열이 하나의 "R"(쥐), 하나의 "C"(치즈), 여러 개의 "X"(통과 할 수없는 블록), " "경로"의 어느 지점에서든 치즈 사이의 (유클리드 거리) 거리를 늘리지 않고 쥐가 치즈에 도달하기 위해 취할 수있는 경로의 수를 찾는 것입니다. 어떻게 내 코드를 잘못 보이는재귀를 사용하여 Java에서 미로 해결

public class RatRoute { 
private static String[] enc; 
private static int count; 
private static int[] r; 
private static int[] c; 

// Test the program 
public static void main(String[] args) { 
    String[] test = { 
      ".R...", 
      "..X..", 
      "....X", 
      "X.X.X", 
      "...C."}; 
    int num1 = numRoutes(test); 
    System.out.println(num1); 
} 

// Set variables, and call recursive function 
public static int numRoutes(String[] enc) { 
    RatRoute.enc = enc;  
    r = findR(enc); 
    c = findC(enc); 
    recursiveHelper(r[0], r[1]); 
    return count; 
} 

// Recursive 
public static void recursiveHelper(int x, int y) { 

    /*System.out.println(); 
    System.out.println(); 
    for (int k = 0; k < enc.length; k++) { 
     System.out.println(enc[k]); 
    }*/ 

    if(isBlock(x,y)) { 
     return; 
    } else if (isBigger(x,y)) { 
     return; 
    } else if (isCheese(x, y)) { 
     count++; 
     //System.out.println("Found the Cheese! Path number: " + count); 
     //System.out.println(); 
     return; 
    } 

    enc[x] = currentPath(x,y);  
    recursiveHelper(x + 1, y); 
    recursiveHelper(x, y + 1); 
    recursiveHelper(x, y - 1); 
    recursiveHelper(x - 1, y); 
    enc[x] = returnPath(x,y); 

} 

// Change the most recently traveled coordinates into a block 
public static String currentPath(int x, int y) { 
    char[] Chars = enc[x].toCharArray(); 
    Chars[y] = 'X'; 
    String newString = String.valueOf(Chars); 
    return newString;  
} 

// Turn path already traveled from blocks back into a usable path to travel (undo the currentPath method) 
public static String returnPath(int x, int y) { 
    char[] Chars = enc[x].toCharArray(); 
    Chars[y] = '.'; 
    String newString = String.valueOf(Chars); 
    return newString;  
} 

// Check if the next movement is into the cheese 
public static boolean isCheese(int x, int y) { 
    if (enc[x].charAt(y) == 'C') { 
     return true; 
    } else { 
     return false; 
    } 
} 

// Check if the next movement is into a block, or outside the given array 
public static boolean isBlock(int x, int y) { 
    if (x == -1 || y == -1 
      || x >= enc.length || y >= enc[x].length()) { 
     return true; 
    } else if (enc[x].charAt(y) == 'X') { 
     //System.out.println(x + "," + y); 
     return true; 
    } else { 
     return false; 
    } 
} 

// See if the distance between the rat and the cheese has gotten larger or smaller 
public static boolean isBigger(int x, int y) { 
    double rx = r[0]; double ry = r[1]; 
    double cx = c[0]; double cy = c[1]; 

    double originalDist = Math.sqrt(Math.pow(rx-cx, 2) + Math.pow(ry-cy, 2)); 
    double newDist = Math.sqrt(Math.pow(x-cx, 2) + Math.pow(y-cy, 2)); 

    //System.out.println("Orginal Distance: " + originalDist); 
    //System.out.println("New Distance: " + newDist); 

    if (newDist > originalDist) { 
     return true; 
    } else { 
     return false; 
    } 
} 

// Find the variables for the original position of the rat 
public static int[] findR(String[] enc) { 
    for (int i = 0; i < enc.length; i++) { 
     for (int j = 0; j < enc[i].length(); j++) { 
      if (enc[i].charAt(j) == 'R') { 
       int[] coordinates = {i, j}; 
       //System.out.println(coordinates[0] + "," + coordinates[1]); 
       return coordinates;     
      } else { 

      } 
     } 
    } 
    int[] other = {-1, -1}; 
    return other; 
} 

// Find the variables for the original position of the rat 
public static int[] findC(String[] enc) { 
    for (int i = 0; i < enc.length; i++) { 
     for (int j = 0; j < enc[i].length(); j++) { 
      if (enc[i].charAt(j) == 'C') { 
       int[] coordinates = {i, j}; 
       //System.out.println(coordinates[0] + "," + coordinates[1]); 
       return coordinates;     
      } else { 

      } 
     } 
    } 
    int[] other = {-1, -1}; 
    return other; 
} 

}

+0

코드의 특정 예에 대한 대답은 도움이된다면 3이 될 것입니다. – Steve

답변

0

이의이 유용 관찰에서 시작하자 :

[...] 그 자체와 ( ) 치즈 사이의 (유클리드 거리) 거리를 늘리지 않고도 경로의 어느 지점에서나.

기본적으로 그것이 의미하는 것은 쥐가 치즈에 더 가까워지면 절대로 먼 위치로 되돌아 가지 않는다는 것입니다.

은 그럼 쥐 X 좌표를 가정 해 봅시다 것은 (즉 x = 2)이이 멀리 전에 치즈를 형성보다 원인이 될 것이기 때문에 3, 치즈 X 좌표는 쥐가 "좌회전"수 5입니다.

이 때문에 간단한 문제의 좋은 방법은 쥐가 갈 수있는 방향을 찾는 것입니다. 귀하의 예에서 쥐는 치즈에서 위로 왼쪽이므로 그렇지 않은 경우에만 치즈에서 멀어지기 때문에 아래로 또는 오른쪽으로 움직일 수 있습니다. 쥐 x이 치즈 x과 일치하면 더 이상 오른쪽이나 왼쪽으로 이동할 수 없으므로 y도 마찬가지입니다. 코드와

, 경우 :

r[0] - c[0] == 0 && r[1] - c[1] == 0 

쥐가 치즈에 도달

r[0] - c[0] = 0 // the rat cannot move on the x any more. 
r[1] - c[1] = 0 // the rat cannot move on the y any more. 

! 이 경우 성공적인 경로를 찾았 기 때문에 카운터를 증가시킬 수 있습니다.

이제 재귀를 사용하여 이것을 실례합시다. 당신이 게시 코드에서 , 우리는 그래서 재귀 방법은 다음과 같을 것이다 (findR(enc) 발견) (findC(enc) 발견) 지정된 c 주어진 r

시작 : 그것은

private void findRoutesFrom(int[] r) { 
    // what directions can the rat go? 
    // if the cheese is on the right of the mouse, xDirection 
    // would be +1. 
    int xDirection = (int) Math.signum(c[0] - r[0]); 
    // if the cheese is below of the mouse, yDirection 
    // would be +1. 
    int yDirection = (int) Math.signum(c[1] - r[1]); 

    // Now, if xDirection is != 0 the rat can attempt to move 
    // in that direction, checking if there's not a block 
    if(xDirection != 0 && !isBlock(r[0] + xDirection, r[1])) { 
     // if it can move in that direction, then use recursion to 
     // find all the possible paths form the new position 
     findRoutesFrom(new int[]{r[0] + xDirection, r[1]}); 
    } 

    // same goes for yDirection 
    if(yDirection != 0 && !isBlock(r[0], r[1] + yDirection)) { 
     findRoutesFrom(new int[]{r[0], r[1] + yDirection}); 
    } 

    // if the rat reaches the cheese, increase the successful 
    // paths counter 
    if(xDirection == 0 && yDirection == 0) { 
     count++; 
    } 
} 

의 그! Eculedean 거리 제약으로 인해 방향이 != 0인지 확인하는 것은 충분합니다. 그 방향이 거짓 일 때 쥐는 더 이상 그 방향으로 이동할 수 없기 때문입니다.

관련 문제