mang_dev
맹꽁거리는 개발자
mang_dev
전체 방문자
오늘
어제
  • 분류 전체보기 (185)
    • Frontend (2)
      • Next.js (1)
    • Backend (3)
      • GraphQL (2)
    • Book (1)
      • 기타 (1)
    • Old (177)
      • 알고리즘 퍼즐 (1)
      • 백준 (131)
      • 프로그래머스 (0)
      • Codility (15)
      • LeetCode (7)
      • Codewars (1)
      • Codeforces (0)
      • Django (6)
      • React (2)
      • Naver Map Api (3)
      • Web UI (4)
      • Introduction to Cloud (2)
hELLO · Designed By 정상우.
mang_dev

맹꽁거리는 개발자

백준 1074번 Z // C++
Old/백준

백준 1074번 Z // C++

2020. 3. 3. 20:23

문제

 

한수는 2차원 배열 (항상 2^N * 2^N 크기이다)을 Z모양으로 탐색하려고 한다. 예를 들어, 2*2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.

만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.

다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.

N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.

다음 그림은 N=3일 때의 예이다.

입력

첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다

출력

첫째 줄에 문제의 정답을 출력한다.

 


 

풀이

 

Divide & Conquer 문제이다.

 

2X2로 이루어진 가장 작은 Z가 될 때까지 계속해서 4칸씩 나누어서 해당 좌표가 속한 칸의 제일 왼쪽 위의 수를 함수 인자로 넘겨주었다.

 

4칸씩 나누어서 각각 칸에다가 번호를 위 그림과 같이 부여했다.

 

그렇게 좌표가 몇 번째 칸에 속해있는지를 확인하였는데, 시작 좌표 + (size / 2)보다 x가 크다면 1을, y가 크다면 2를 더해주면 몇 번째 칸인지를 구할 수 있다.

 

시작 좌표의 수는 다음과 같은 식으로 구했다.

몇 번째 칸 * pow(4, log2(size) - 1)

 

코드

더보기
#include <iostream>
#include <cmath>

using namespace std;

int N, R, C;

void solve(int start, int size, int x, int y);

int main() {
	cin >> N >> R >> C;

	int size = 1;
	for (int i = 0; i < N; i++)
		size *= 2;
	
	solve(0, size, 0, 0);

	return 0;
}

void solve(int start, int size, int x, int y) {
	size /= 2;

	int count = 0;

	if (C >= x + size) {
		x += size;
		count++;
	}
	
	if (R >= y + size) {
		y += size;
		count += 2;
	}

	if (size == 1) {
		cout << start + count;
		return;
	}

	int temp = pow(4, log2(size * 2) - 1);

	start = start + count * temp;

	solve(start, size, x, y);
}
저작자표시 (새창열림)

'Old > 백준' 카테고리의 다른 글

백준 1992번 쿼드트리 // C++  (0) 2020.03.04
백준 7662번 이중 우선순위 큐 // C++  (0) 2020.03.03
백준 5525번 IOIOI // C++  (0) 2020.03.03
백준 1931번 회의실 배정 // C++  (0) 2020.03.03
백준 1780번 종이의 개수 // C++  (0) 2020.03.03
    'Old/백준' 카테고리의 다른 글
    • 백준 1992번 쿼드트리 // C++
    • 백준 7662번 이중 우선순위 큐 // C++
    • 백준 5525번 IOIOI // C++
    • 백준 1931번 회의실 배정 // C++
    mang_dev
    mang_dev

    티스토리툴바