package task.easy.z1074;
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br;
static StringTokenizer st;
static int N;
static int r;
static int c;
static int count = 0;
static int[] dr;
static int[] dc;
static int result = 0;
public static void main(String[] args) throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
// dxdy 정의
dr = new int[] {0, 0, 1, 1};
dc = new int[] {0, 1, 0, 1};
zProcess(N,0, 0);
System.out.println(result);
}
public static void zProcess(int level, int startRow, int startCol) {
if (result > 0) {
return;
}
if (level == 1) {
for (int i = 0; i < 4; i++) {
if (startRow+dr[i] == r && startCol+dc[i] == c) {
result = count;
return;
}
count++;
}
} else {
for (int i = 0; i < 4; i++) {
int posDivided = (int) Math.pow(2, level - 1);
if (dr[i]*posDivided+startRow <= r
&& dr[i]*posDivided+startRow + Math.pow(2, level-1) > r
&& dc[i]*posDivided+startCol <= c
&& dc[i]*posDivided+startCol + Math.pow(2, level-1) > c
) {
zProcess(level-1, dr[i]*posDivided+startRow, dc[i]*posDivided+startCol);
} else {
count += (int) ((int) Math.pow(2, level-1) * Math.pow(2, level-1));
}
}
}
}
}
Z방향으로 서치를 진행하므로 2사분면 1사분면 3사분면 4사분면 순서로 진행한다. 만약 해당 사분면내부에 r,c가 존재하지 않는 다면 해당 사분면의 크기를 count에 누적시킨다.
만약 r,c가 존재하는 사분면일 경우 해당 사분면에 대하여 다시 zProcess를 돌린다. 사분면안에서 다시 나뉜 2,1,3,4 사분면에 대해서 이전과 동일한 로직이 작동될 것이다. 또 다시 3가지의 사분면은 계산활동이 거의 무시된다.
이런식으로 빠르게 봐도 될 영역은 한번에 계산하고, 주의깊게 봐야할 영역만 재귀함수를 켜주는 식으로 진행한다.