백준이당

[C++] 백준 1074번 : Z

이히당 2023. 8. 1. 01:04

 

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

 

1074번: Z

한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을

www.acmicpc.net

분할정복 문제이다.

그치만 이 문제에서 모든 곳을 다 돌아다니며 원하는 결과를 얻어내려고 한다면, 시간초과가 난다.

#include <iostream>
#include <stack>
#include <vector>
#include <cmath>

#include<algorithm>


using namespace std;

int r,c;
int** board;
int turn = 0;
int dynamicX[4] = {0, 0, 1, 1};
int dynamicY[4] = {0, 1, 0, 1};
bool flag = true;


void draw(int x, int y) {
	
	// draw Z
	for (int i = 0; i < 4; i++) {
		board[x + dynamicX[i]][y + dynamicY[i]] = turn++;
	}
}

void divideDraw(int n, int x, int y) {

	if (x == r && y == c) {

		flag = false;
		printf("%d",turn);

	}
	
	if ( pow(x%2,n) == 0 && pow(y%2,n) == 0 && flag) {
		turn--;
		// draw Z
		for (int i = 0; i < 4 && flag; i++) {
//			board[x + dynamicX[i]][y + dynamicY[i]] = turn++;
			
			if (n > 0) {
				turn++;
				int currX = x + pow(2,n-1) * dynamicX[i];
				int currY = y + pow(2,n-1) * dynamicY[i];

				divideDraw(n-1, currX, currY);
			}

		}
	} 

	
	

}


int main() {
	int n ;
	cin >> n >> r >> c;
		

	
	divideDraw(n,0,0);
	
	
	
	return 0;
}

 

위의 코드가 모든 방을 다 돌아다니는 거다.

하루죙일고민해서짰는데 시간초과나서 진짜 노트북을 박살내고싶었따ㅠㅠㅠㅠㅠㅠ

멍청한 내탓이지 뭐..

 

#include <iostream>
#include <stack>
#include <vector>
#include <cmath>

#include<algorithm>


using namespace std;

int r,c;
//int** board;
int loc = 0;
//int dynamicX[4] = {0, 0, 1, 1};
//int dynamicY[4] = {0, 1, 0, 1};
//bool flag = true;




void findZLoc(int n, int x, int y) {
	if (n > 0) {
		int currPoint = pow(2, n-1);
		int areaX = x >= currPoint ? 1 : 0;
		int areaY = y >= currPoint ? 1 : 0;
		int area = areaX*2 + areaY;
		loc += (currPoint * currPoint) * area;
		findZLoc(n-1, x % currPoint, y % currPoint);
	} else {
		cout << loc;
	}
}


int main() {
	int n ;
	cin >> n >> r >> c;

	
	findZLoc(n,r,c);
	
	
	
	return 0;
}

 

알고 겁나 잘하는 지인에게 힌트를 받고 내 잘못된 점을 반성해서 다시짰다.

생각보다 금방 짰다.

아이디어는 전체를 4공간으로 자르고, 찾으려는 방이 4구역 중 어디있는지 고려하는 방식으로 쭉쭉쭉 분할 정복해나가는 것이다.

1~4구역중 한 곳을 찾으면, 그 까지 나올 수 있는 차례를 단순 덧셈해주는 식으로 구했다.

 

728x90