[백준] 17829번 222-풀링
문제링크: 백준 17829 222-풀링
-
아이디어
2x2 행렬까지 들어간 후 2번째로 큰 값을 구하면서 점점 나오는 구조.
2x2 행렬에서는 4개의 숫자를 구한 후 정렬을 하여 뒤에서 2번째 수를 리턴하면 된다.
2x2 행렬이 될 때까지 재귀함수로 깊이 들어감.
단, 재귀에서 나올 때 2번째 수를 가지고 나와야 한다.
-
시간복잡도
행렬의 가로(세로) N: 2 <= N <= 1,024
재귀호출의 최대 횟수: 최대 크기인 1,024x1,024를 2x2로 쪼개면 2^9 * 2^9 = 2^18개 = 262,144번
Arrays.sort정렬: O(N^2) => 1,024x1,024 = 1,048,576번
=> 연산량 1억번 넘지 않음
-
자료구조
행렬의 가로(세로) N: 2 <= N <= 1,024 ==> int 가능
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static int[][] grid;
public static int n;
public static int solution(int x, int y, int n) {
return pulling(0, 0, n);
}
// 사각형이 더 쪼갤 수 있으면 재귀호출
public static int pulling(int x, int y, int n) {
// 마지막 재귀에 도착했을땐 2x2 배열일때.
// 이때 a,b,c,d를 가지고 2번째 숫자 구해줘서
int a = grid[x][y];
int b = grid[x+1][y];
int c = grid[x][y+1];
int d = grid[x+1][y+1];
// 만약 2보다 크면 계속 재귀 먼저 들어감
// 그리고 다 하고 나올때는 거기서 계산해온 2번째 큰 값 가지고 나옴
if(n != 2) {
a = pulling(x, y, n / 2);
b = pulling(x, y + (n / 2), n / 2);
c = pulling(x + (n / 2), y, n / 2);
d = pulling(x + (n / 2), y + (n / 2), n / 2);
}
// pulling 재귀함수의 리턴값으로 밖으로 내보냄
return secondNum(a, b, c, d);
}
// 2번째 큰 수 추출, 매개변수는 2X2 배열의 구성요소
public static int secondNum(int a, int b, int c, int d) {
int[] arr = new int[4];
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
Arrays.sort(arr);
return arr[2];
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
grid = new int[n][n];
for (int i = 0; i < n; i++) {
String[] s = br.readLine().split(" ");
for (int j = 0; j < n; j++) {
grid[i][j] = Integer.parseInt(s[j]);
}
}
System.out.println(solution(0, 0, n));
}
}
-
학습내용
들어가면서 계산해서 끝내는게 아니라 다 들어간 다음에 나오면서 계산을 완성해가는 것은
재귀해서 나온 값을 변수에 받아 나와야 한다. (위 문제에서는 pulling 메서드를 변수 a, b, c, d로 각각 받음)
-
다른 풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int[][] map;
static int N;
public static void main(String[] args) throws NumberFormatException, IOException {
N = Integer.parseInt(br.readLine());
map = new int[N][N];
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine()," ");
for(int j=0; j<N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int answer = parse(N,0,0);
System.out.println(answer);
}
private static int parse(int n,int r, int c) {
if(n==2) {
int[] ary = new int[4];
ary[0] = map[r][c];
ary[1] = map[r][c+1];
ary[2] = map[r+1][c];
ary[3] = map[r+1][c+1];
Arrays.sort(ary);
return ary[2];
}
// 별도 메서드 없이 바로 가져다가 만들어도 되네
int[] arr = new int[4];
arr[0] = parse(n/2, r, c);
arr[1] = parse(n/2, r, c+n/2);
arr[2] = parse(n/2, r+n/2, c);
arr[3] = parse(n/2, r+n/2, c+n/2);
Arrays.sort(arr);
return arr[2];
}
}
마지막 수정일시: 2022-07-07 00:44
댓글남기기