포스트

Z(1074)

Z(1074)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.io.*;
import java.util.*;

public class Main{
    
  // 각 구역의 시작 값
  static int[] value = new int[4];
  
  public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    StringBuilder sb = new StringBuilder();
    
    StringTokenizer st = new StringTokenizer(br.readLine());
    
    int n = Integer.parseInt(st.nextToken()), r = Integer.parseInt(st.nextToken()), c = Integer.parseInt(st.nextToken());
    
    // 구역의 절반 지점, 증가폭, 2의 제곱수
    int[] two = new int[n];
    
    int temp = 1;
    for(int i = 0; i < n; i++){
      two[i] = temp;
      temp *= 2;
    }
    
    while(--n > -1){
      valueSetting(two[n]);
      
      if(r < two[n] && c < two[n]){ // 1구역
        value[0] = value[0];
      } else if(r < two[n] && c >= two[n]){ // 2구역
        value[0] = value[1];
        c -= two[n]; // 구역의 시작점이 바뀌었으므로
      } else if(r >= two[n] && c < two[n]){ // 3구역
        value[0] = value[2];
        r -= two[n];
      } else if(r >= two[n] && c >= two[n]){ // 4구역
        value[0] = value[3];
        c -= two[n];
        r -= two[n];
      }
    }
    
    sb.append(value[0]);
    
    bw.write(sb.toString());
    bw.flush();
    bw.close();
    br.close();
  }
  
  public static void valueSetting(int n){
    for(int i = 1; i < 4; i++){
      value[i] = value[0] + (n * n) * i;
    }
  }
}

풀이과정

  1. 처음에는 가로와 세로의 번호를 사용하여 2차배열로 접근을 하려고 했다.
  2. 그렇게 하니 가로와 세로에 대한 절반의 기준점을 각각 관리해야했고, 코드도 복잡해져 계산이 어려워졌다.
  3. 그래서 기준점을 하나로 이용하되 가로와 세로의 입력값을 변화시키는 방향으로 바꿨다.
  4. 문제를 풀며 어려웠던 점은 길이의 절반이 되는 지점(구역을 4개로 나누어 입력받은 위치를 좁혀 나가기 위해 사용)
  5. 그리고 각 구역의 시작값
  6. 4와 5를 각각 계산하며, 계산된 값들을 매칭하여야 했기 때문에 감은 잡혔지만 막상 계산을 통한 구현을 하려니 머리가 복잡하였다.
  7. 막상 코드로 풀어놓고 보면 크게 어렵지는 않았던 것 같다.
  • 성공
  • 메모리 : 14220 KB
  • 시간 : 128 ms

보안점

  1. 다른 사람의 풀이를 보니
  2. Math.pow()라는 제곱근을 반환시켜주는 함수의 존재를 알게되었다.
  3. 난 각 구역에 따라 기준점이 변화되기 때문에 입력받은 r과 c의 값에서 기준점을 빼는 연산을 하였고, r과 c의 크기를 기준점과 비교하여 구역을 정하는 방식으로 했었다.
  4. 다른 방법으로는 r과 c를 기준점과 나눈 나머지를 값으로 대입하여 변화시켰고, r과 c의 크기를 비교하는 방식이 아닌 기준점으로 나누어 몫에 따라 구역을 분리하는 코드도 좋은 접근 방식이라 생각되었다.
  5. 또한 나는 반복문으로 풀었는데, 재귀함수로 접근하여 풀었던 사람들도 꽤 되었다.