네이버 웹툰 3번문제의 달팽이가 생각난다. 물론 다른 문제이긴 하지만, 이런 문제를 잘 풀지 못하는 것 같기에 풀어보려 한다.
(역시나 한시간 걸렸다.)
이 문제는 silver1 문제다
Z 모양으로 탐색하려 한다. 배열의 크기는 2 ^ Nx 2^N 이다.
N >1 이라면, 배열을 2^(N-1) x 2^(N-1) 로 2^N 등분 한 후, 재귀적으로 순서대로 방문한다.
먼저 몇 번째 칸에 속해있는지를 찾아야 한다.
재귀적으로 순서를 찾아야 한다.
4등분씩 해 나가기 때문에, 각 각에서 몇 번째 칸에 속해있는지 찾아야 한다. 맨 마지막에 Z순으로 2x2에서 돌 때 몇 번째에 방문하게 되는 것인지만 구하면 된다.
N =3 이고, r = 5, c = 5 . 4등분한 사각형을 Z로 방문한다 생각했을 때 몇 번 째 칸에 속했는지를 먼저 알아야 한다.
첫 번째 호출
두 번째 호출
즉, 아래와 같이 풀면 될 것 같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main{
public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static int n,r,c;
public static void Setting() throws IOException {
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
}
public static int solve(){
int preR =0,preC =0;
int nextR=0,nextC=0;
int cnt=0;
int len = (int)Math.pow(2,n);
// len 은 2의 n승인 것들만 온다.
while(len>2){
len/=2;
preR = nextR; preC = nextC;
if( r< preR +len){
// 첫 번째 칸
if(c<preC +len){
nextR = preR;
nextC = preC;
}
// 두 번째 칸
else{
nextR = preR;
nextC = preC + len;
cnt += (len*len);
}
}else{
// 세 번째 칸
if(c<preC +len){
nextR = preR +len;
nextC = preC;
cnt += (len*len)<<1;
}
// 네 번째 칸
else{
nextR = preR +len;
nextC = preC + len;
cnt += (len*len)*3;
}
}
}
// nextR, nextC 에서 ,r,c의 위치를 찾아야함
if(r<nextR+1){
if(c<nextC+1)return cnt;
else return cnt+1;
}else{
if(c<nextC+1)return cnt+2;
else return cnt+3;
}
}
public static void main(String[] args) throws IOException {
Setting();
int res = solve();
System.out.println(res);
}
}