[SWEA1861] 정사각형 방

2 분 소요

[SWEA1861] 정사각형 방

SWEA 1861 정사각형 방 - 로그인이 필요합니다.

문제 설명

  • N*N 배열의 각 방은 1~N^2 의 번호가 붙어있다.

  • 하나의 방에서 상하좌우 로 움직일 수 있다.

  • 이동할 때는 현재 방번호보다 딱 1만큼 큰 방으로만 움직일 수 있다.

  • 가장 많이 움직일 때의 이동한 방의 개수와 그럴때의 시작 방의 번호를 출력하면 된다.

접근방법

  • 먼저 배열을 입력받을때, 구조체로 x좌표와 y좌표가 저장된 새로운 배열을 하나 만들어서 그 배열의 인덱스엔 방번호, 그리고 그 배열값으로 배열의 x좌표 y좌표를 적어주는 전처리 과정 을 한다.

  • 위의 전처리를 하는 이유는 한번 방이동을 한 후 다음 번호를 찾기위한 시간을 줄이기 위한 이유이다. 전처리를 해두면, 인덱스 번호로 바로 방번호를 참조할 수 있으므로 상수시간에 방에 들어있는 번호를 찾을 수 있다.

  • 방번호가 1인곳부터 시작하여 DFS를 한다. 더이상 DFS를 진행할 수 없을 경우 방번호와 이동한 방의 개수를 저장한다.

  • 그 다음 탐색할 방은 그 전단계에서 DFS로 탐색을 하여 도착한 마지막 방번호 +1 을 시작할 방 으로 정하면 된다.

  • 첫번째 탐색이 1번방~ 10번방까지 갔을 경우, 11번방부터 새로 탐색을 하는 것이다. 2번방부터 조사하지 않는 이유는 2번방역시 10번방까지 가고 더이상 탐색을 못할 것이기때문에 1번방~10번방까지 탐색한 방의 개수가 무조건 더 클것이기 때문이다.

코드리뷰

  • 최대한 실행시간을 줄이는데 초점을 맞추고 풀어보았다.

  • D4문제라기엔 난이도가 쉬운 편.

  • 오랜만에 문제풀어서 재밌었다..

#include <iostream>
using namespace std;

int N;
int board[1005][1005];
int check[1005][1005];
int tmp_num, tmp_result;
int dc[4] = { 0,0,-1,1 };
int dr[4] = { -1,1,0,0 };

typedef struct {
	int x;
	int y;
}pre_process;

typedef struct {
	int start_pos;
	int end_pos;
	int maxnum;
}MAX;

pre_process pre_board[1000005];
MAX result;

void dfs(int start) {
	int xnow = pre_board[start].x;
	int ynow = pre_board[start].y;
	tmp_result += 1;
	result.end_pos = start;
	check[xnow][ynow] = 1;
	for (int k = 0; k < 4; k++) {
		int xnext = xnow + dc[k];
		int ynext = ynow + dr[k];
		if (xnext < 0 || xnext >= N || ynext < 0 || ynext >= N || check[xnext][ynext] == 1 || board[xnext][ynext] != board[xnow][ynow] + 1)
			continue;
		dfs(start+1);
		check[xnext][ynext] = 0;
		return;
	}
}

int main() {
	int T;
	scanf("%d", &T);
	for (int t = 1; t <= T; t++) {
		scanf("%d", &N);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				scanf("%d", &board[i][j]);
				pre_board[board[i][j]].x = i;
				pre_board[board[i][j]].y = j;
			}
		}
		int start = 1;
		while (start <= N * N) {
			tmp_num = start;
			dfs(start);
			check[pre_board[start].x][pre_board[start].y] = 0;
			if (tmp_result > result.maxnum) {
				result.start_pos = tmp_num;
				result.maxnum = tmp_result;
			}
			tmp_result = 0;
			start = result.end_pos + 1;
		}
		printf("#%d %d %d\n", t, result.start_pos, result.maxnum);
		result.start_pos = 0;
		result.end_pos = 0;
		result.maxnum = 0;
	}
	return 0;
}

댓글남기기