파게로그
[백준 1074번] 재귀로 Z 모양 그리기 본문
문제 링크: 1074번 Z
https://www.acmicpc.net/problem/1074
Z를 그리되, 0부터 원하는 위치까지 모두 일일이 그린다면 시간 초과로 이 문제를 풀 수 없다. 따라서 분할 정복 기법을 활용하여 몇 번 사각형에 속하는지 확인하는 방식을 취한다.
solution()
에서의 n
은 변의 길이이고, start
는 사각형의 좌상단 숫자이므로 가장 처음에 n
에는 2^N를, start
에는 0을 넣어준다. 그리고 r
, c
를 통해서 1, 2, 3, 4번 사각형 중 어디에 속하는지를 판단하고 해당 사각형에 대해 solution()
을 호출한다. 다만 r
과 c
는 최초의 사각형을 기준으로 하고 있기에, 분할된 사각형을 기준으로 갱신되어야 하는데, 행 또는 열, 또는 행과 열 모두에서 n/2를 빼줌으로써 갱신할 수 있다. start
는 변의 길이 n
을 활용하여 구한다.
이런 식으로 사각형을 분할하는 것을 변의 길이가 1이 될 때까지 계속한다. 이 때에는 start
가 그 자체로 찾는 값이므로 이를 반환한다.
리턴 조건을 n==2
로 두고, r==0 && c==0
일 때 start
를, r==0 && c==1
일 때 start+1
을, r==1 && c==0
일 때 start+2
를, r==1 && c==1
일 때 start+3
을 반환하도록 하여 보다 직관적인 코드를 작성할 수도 있다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int pow(int n, int exp) {
int res = 1;
for (int i = 0; i < exp; i++)
res *= n;
return res;
}
static int solution(int n, int r, int c, int start) {
if (n==1)
if (r==0&&c==0) return start;
int newStart;
if (r < n/2) {
if (c < n/2) { // 1번 사각형
newStart = start;
} else { // 2번 사각형
newStart = start+(n/2)*(n/2);
c -= n/2;
}
} else {
if (c < n/2) { // 3번 사각형
newStart = start+(n/2)*(n/2)*2;
r -= n/2;
} else { // 4번 사각형
newStart = start+(n/2)*(n/2)*3;
c -= n/2;
r -= n/2;
}
}
return solution(n/2, r, c, newStart);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
System.out.println(solution(pow(2, n), r, c, 0));
}
}
'콤퓨타 왕왕기초 > PS' 카테고리의 다른 글
[백준 11053번] LIS(최장 증가 부분 수열) DP (0) | 2021.04.07 |
---|---|
[백준 17298번] 오큰수 (0) | 2021.03.30 |
[백준 2470번] 두 용액 (0) | 2021.03.02 |
[백준 10800번] 컬러볼 (0) | 2021.02.25 |
[백준 17825번] 주사위 윷놀이 (0) | 2021.02.18 |
Comments