문제
https://www.acmicpc.net/problem/1074
1074번: Z
한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을
www.acmicpc.net
코드
첫번째 시도(시간 초과)
#include <iostream>
#include <cmath>
using namespace std;
int n, r, c, cnt = 0;
void zSearch(int y, int x, int len){
if(len==1){
if(y==r && x==c){
cout << cnt;
} else{
cnt++;
}
return;
}
int d = len/2;
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
zSearch(y+i*d, x+j*d, d);
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> r >> c;
int len = pow(2, n);
zSearch(0,0,len);
return 0;
}
정답
#include <iostream>
#include <cmath>
using namespace std;
int n, r, c, cnt = 0;
void zSearch(int y, int x, int len){
if(len==1){
if(y==r && x==c){
cout << cnt;
return;
}
}
int d = len/2;
if(r<y+d && c<x+d){ // 왼쪽 위칸
zSearch(y, x, d);
}else if(r<y+d && c>=x+d){ // 오른쪽 위칸
cnt += pow(d, 2);
zSearch(y, x+d, d);
}else if(r>=y+d && c<x+d){ // 왼쪽 아래칸
cnt += 2*pow(d, 2);
zSearch(y+d, x, d);
}else{ // 오른쪽 아래칸
cnt += 3*pow(d, 2);
zSearch(y+d, x+d, d);
}
}
int main(){
cin >> n >> r >> c;
int len = pow(2, n);
zSearch(0,0,len);
return 0;
}
정리
이 문제는 위의 첫번째 시도처럼 모든 경우의 수를 탐색해면 시간초과가 걸려 문제 푸는 데 실패하게 된다.
이 문제는 좌표가 주어지기 때문에 모두 탐색할 필요가 없고 특정 조건에 따라 왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래 중 하나만을 탐색하면 된다.
분할 정복 문제이면서 시간까지 고려해야하는 문제이다.
참조
'Beakjoon > divide & conquer' 카테고리의 다른 글
[백준] 1992번 쿼드트리 (C++) - divide & conquer (0) | 2022.02.17 |
---|---|
[백준] 2447번 별 찍기 - 10 (C++) - divide & conquer (0) | 2022.02.16 |
[백준] 1780번 종이의 개수 (C++) - divide & conquer (0) | 2022.02.16 |
[백준] 2630번 색종이 만들기 (C++) - divide & conquer (0) | 2022.02.03 |