로봇은 사방으로 이동할 수 있으며 각 방향을 이동할 확률이 주어진다.
로봇이 총 n번 이동한다.
이미 방문한 경로에 또 방문하는 경우를 단순하지 않은 경로, 그렇지 않은 경로를 단순한 경로라고 한다.
로봇이 단순한 경로로 이동할 확률을 구해라
n ≤ 14
move()
호출 부분을 부분에 나와있다.import java.io.*;
import java.util.*;
public class Main {
static int n;
static double ans = 0;
static double[] p = new double[4]; // E(동), W(서), S(남), N(북)쪽으로 이동할 확률
static int[] dr = {0, 0, 1, -1};
static int[] dc = {1, -1, 0, 0};
static boolean[][] visited = new boolean[30][30];
// 백트래킹으로 모든 경로를 이동해보며 단순한 경로인지 확인
// move: 지금까지 움직인 횟수, cr: 현재 있는 행, cc: 현재 있는 열
private static void move(int move, int cr, int cc, double per) {
if (move == n) { // n번 만큼 이동한 경우
ans += per;
return;
}
for (int dir = 0; dir < 4; ++dir) {
int nr = cr + dr[dir];
int nc = cc + dc[dir];
if (visited[nr][nc]) continue; // 이미 방문한 곳인 경우
visited[nr][nc] = true;
move(move + 1, nr, nc, per * p[dir]);
visited[nr][nc] = false;
}
}
// 변수 입력 받기
private static void readData() throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(st.nextToken());
for (int i = 0; i < 4; ++i) {
p[i] = Integer.parseInt(st.nextToken()) * 0.01;
}
br.close();
}
// 데이터 쓰기
private static void writeData() throws Exception {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
sb.append(ans).append("\n");
bw.write(sb.toString());
bw.flush();
bw.close();
}
public static void main(String[] args) throws Exception {
readData();
visited[15][15] = true;
move(0, 15, 15, 1);
writeData();
}
}
각 방향으로 이동할 확률을 나타내는 변수 (double[] p
)를 입력받을 때
p[i] = Integer.parseInt(st.nextToken()) / 100;
을 썼더니 모든 확률이 0.0으로 저장됐다.
int
/ int
연산double
로 casting 되는데따라서 int * double로 연산하여 의도한 값이 저장되도록 변경하여 문제를 해결할 수 있었다.