알고리즘/BOJ
[BOJ] 1074. Z
재담
2022. 2. 28. 16:21
문제 원본 : https://www.acmicpc.net/problem/1074
1074번: Z
한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을
www.acmicpc.net
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static List<Integer> list = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int[] arr = new int[n];
int p = 2;
arr[0] = 1;
for (int i = 1; i < n; ++i) {
arr[i] = arr[i - 1] + p;
p <<= 2;
}
preProc(n, arr);
int ans = 0;
for (int i = 0; i < r; ++i) {
ans += list.get(i) * 2;
}
for (int i = 0; i < c; ++i) {
ans += list.get(i);
}
bw.write(Integer.toString(ans));
bw.close();
br.close();
}
public static void preProc(int level, int[] arr) {
if (level == 1) {
list.add(arr[0]);
return;
} else {
preProc(level - 1, arr);
list.add(arr[level - 1]);
preProc(level - 1, arr);
}
}
}
- 전형적인 분할 정복 문제인데 좀 다르게 풀어 보았다.
- 사분면은 신경 쓰지 않고 행과 열이 증가함에 따른 규칙을 발견하고 적용해서 풀었다.
- 행의 증가 규칙은 N=4일 때 2 6 2 22 2 6 2 86 2 6 2 22 2 6 2
- 열의 증가 규칙은 N=4일 때 1 3 1 11 1 3 1 43 1 3 1 11 1 3 1
- 일단 행의 증가량이 열의 증가량의 2배이다.
- 숫자 배열은 (N-1까지 공차 배열) N일 때 공차 (N-1까지 공차 배열)의 규칙을 가진다.
- 이 부분을 재귀(preProc 메서드)로 구해주었다.
- 그리고 1 3 11 43의 규칙을 살펴보니 공차가 2 8 32로 4배씩 증가하는 것을 알 수 있었다.
- 그래서 공차 배열을 먼저 다 구하고 r과 c까지 r은 2배를 더하고 c는 그냥 더해주면 된다.