본문 바로가기
백준

[1891] 사분면

by kmyobin 2022. 11. 14.


https://www.acmicpc.net/problem/1891

 

1891번: 사분면

첫 줄에 이동시키려는 사분면 조각 번호의 자릿수를 나타내는 정수 d와, 그 사분면 조각의 번호가 주어진다. (1 ≤ d ≤ 50) 둘째 줄에는 이동의 내용을 나타내는 두 정수가 x, y가 주어진다. (|x|, |y|

www.acmicpc.net

재귀를 사용하였다.

 

 

사분면을 좌표로, 좌표를 사분면으로 만드는 함수를 작성하였다.

일단 string으로 사분면 조각의 번호를 받고 int형 배열에 나눠 담아주었다.

	for (int i = 0; i < d; i++) {
		A[i] = input[i] - '0'; // char to int
	}

 

 

그 다음 생기는 좌표의 범위를 계산해주었다.

d=1일 때는 2*2 배열이 생성되고, d=3일 때는 8*8 배열이 생성되므로 

(2^d)*(2^d) 배열이 생성됨을 알 수 있다.

이 때 2의 50승(1,125,899,906,842,624)은 int형의 범위(2,147,483,647)를 넘어가므로 자료형은 long long int(9,223,372,036,854,775,807)를 써주었다.

 

 

그 다음 사분면으로 입력 받았으니 좌표로 바꿔야 한다.

그림으로 설명해보았다. 

 

아까 사분면의 조각 번호를 int형 배열에 옮겨담았었다.

제일 큰 사분면부터 시작하여 위의 조건을 d번 실행하면 좌표로 변환되어 출력할 수 있다.

void quadtoxy(ll min_x, ll max_x, ll min_y, ll max_y, int i) {
	// 사분면을 좌표로
	if (i == d) { // 사분면 자릿수 다 돌았으면
		x = min_x; y = min_y; // x, y에 넣음
		return;
	}
	ll xmid = (min_x + max_x) / 2;
	ll ymid = (min_y + max_y) / 2;

	if (A[i] == 1) { // 1사분면
		quadtoxy(xmid, max_x, min_y, ymid, i + 1);
	}
	else if (A[i] == 2) { // 2사분면
		quadtoxy(min_x, xmid, min_y, ymid, i + 1);
	}
	else if (A[i] == 3) { // 3사분면
		quadtoxy(min_x, xmid, ymid, max_y, i + 1);
	}
	else { // 4사분면
		quadtoxy(xmid, max_x, ymid, max_y, i + 1);
	}
}

 

 

이제 움직일 좌표를 입력받는다.

내 좌표는 y축이 아래로 갈 수록 증가하는 좌표이므로 입력 받은 y축 성분 값을 마이너스를 붙여준다.

	cin >> a >> b;
	b = (-b); // b는 위로 가는게(마이너스) 양수 취급을 받으므로 반대로 음수로 만들어야함
	x += a; y += b;

 

 

범위 밖이면 -1을 출력해야하므로 그에 따른 조건문을 작성한다.

	if (x >= n || x < 0 || y >= n || y < 0) { // 범위 밖이면
		printf("-1");
	}
	else {
		xytoquad(0, n, 0, n, 0);
	}

 

 

이제 다시 좌표를 사분면으로 바꿔줘야한다.

조건은 아까 그 그림과 동일하다.

void xytoquad(ll min_x, ll max_x, ll min_y, ll max_y, int i) {
	// 좌표를 사분면으로
	if (i == d) { // 사분면 다 찼으면
		return;
	}
	ll xmid = (min_x + max_x) / 2;
	ll ymid = (min_y + max_y) / 2;

	if (xmid <= x && x < max_x &&
		min_y <= y && y < ymid) { // 1사분면
		printf("1");
		xytoquad(xmid, max_x, min_y, ymid, i + 1);
	}
	else if (min_x <= x && x < xmid &&
		min_y <= y && y < ymid) { // 2사분면
		printf("2");
		xytoquad(min_x, xmid, min_y, ymid, i + 1);
	}
	else if (min_x <= x && x < xmid &&
		ymid <= y && y < max_y) { // 3사분면
		printf("3");
		xytoquad(min_x, xmid, ymid, max_y, i + 1);
	}
	else { // 4사분면
		printf("4");
		xytoquad(xmid, max_x, ymid, max_y, i + 1);
	}
}

 

 

따라서 전체 코드는 아래와 같다.

#include <iostream>
#include <cmath>
#include <string>
typedef long long int ll; // 2의 50승이 크므로
using namespace std;

int d;  int A[50];
ll x; ll y;
ll a; ll b;
string input;

void quadtoxy(ll min_x, ll max_x, ll min_y, ll max_y, int i) {
	// 사분면을 좌표로
	if (i == d) { // 사분면 자릿수 다 돌았으면
		x = min_x; y = min_y; // x, y에 넣음
		return;
	}
	ll xmid = (min_x + max_x) / 2;
	ll ymid = (min_y + max_y) / 2;

	if (A[i] == 1) { // 1사분면
		quadtoxy(xmid, max_x, min_y, ymid, i + 1);
	}
	else if (A[i] == 2) { // 2사분면
		quadtoxy(min_x, xmid, min_y, ymid, i + 1);
	}
	else if (A[i] == 3) { // 3사분면
		quadtoxy(min_x, xmid, ymid, max_y, i + 1);
	}
	else { // 4사분면
		quadtoxy(xmid, max_x, ymid, max_y, i + 1);
	}
}

void xytoquad(ll min_x, ll max_x, ll min_y, ll max_y, int i) {
	// 좌표를 사분면으로
	if (i == d) { // 사분면 다 찼으면
		return;
	}
	ll xmid = (min_x + max_x) / 2;
	ll ymid = (min_y + max_y) / 2;

	if (xmid <= x && x < max_x &&
		min_y <= y && y < ymid) { // 1사분면
		printf("1");
		xytoquad(xmid, max_x, min_y, ymid, i + 1);
	}
	else if (min_x <= x && x < xmid &&
		min_y <= y && y < ymid) { // 2사분면
		printf("2");
		xytoquad(min_x, xmid, min_y, ymid, i + 1);
	}
	else if (min_x <= x && x < xmid &&
		ymid <= y && y < max_y) { // 3사분면
		printf("3");
		xytoquad(min_x, xmid, ymid, max_y, i + 1);
	}
	else { // 4사분면
		printf("4");
		xytoquad(xmid, max_x, ymid, max_y, i + 1);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> d >> input;
	for (int i = 0; i < d; i++) {
		A[i] = input[i] - '0'; // char to int
	}

	ll n = 1;
	for (int i = 0; i < d; i++) {
		n *= 2; // 생기는 좌표 범위는 0~n-1
	}
	quadtoxy(0, n, 0, n, 0); // 사분면을 좌표로

	cin >> a >> b;
	b = (-b); // b는 위로 가는게(마이너스) 양수 취급을 받으므로 반대로 음수로 만들어야함
	x += a; y += b; 

	if (x >= n || x < 0 || y >= n || y < 0) { // 범위 밖이면
		printf("-1");
	}
	else {
		xytoquad(0, n, 0, n, 0);
	}
}

이러케 지저분하게 푸는게 맞을까?

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

[1912] 연속합  (0) 2022.11.18
[2263] 트리의 순회  (0) 2022.11.17
[2448] 별 찍기 - 11  (0) 2022.11.13
[1074] Z  (0) 2022.11.12
[2630] 색종이 만들기  (0) 2022.11.08

댓글