본문 바로가기
알고리즘/[ADV] 삼성 SW Expert Academy A형

SWEA 2105 : 디저트 카페 (모의 SW 역량테스트)

by 피로물든딸기 2021. 5. 17.
반응형

 

SW 역량테스트 합격하기 A형 강의 오픈!! (인프런 바로가기)

 

삼성 A형 전체 링크

 

모의 SW 역량테스트 문제집

 

디저트 카페 링크

 

이후 설명 및 입/출력은 링크 참고

 

MAP의 좌표는 (1, 1)부터 시작하도록 입력을 받는다.

int T, N;
int MAP[MAX][MAX];

void input()
{
	scanf("%d", &N);
	for (int r = 1; r <= N; r++)
		for (int c = 1; c <= N; c++)
			scanf("%d", &MAP[r][c]);
}

 

움직일 수 있는 길은 오른쪽 아래부터 시작하여 시계 방향이므로, dr, dc를 잘 mapping 시킨다.

반드시 시계 방향으로 정의해야 한다.

/* 순서대로 오른쪽 아래, 왼쪽 아래, 왼쪽 위, 오른쪽 위 */
int dr[] = { 1, 1, -1, -1 };
int dc[] = { 1, -1, -1, 1 };

 

매 tc마다 dir = 0 (오른쪽 아래)부터 시계 방향으로 길을 잘 만들어가면 된다.

dessert 배열에는 먹은 디저트를 표시한다. 

가장 작은 마름모를 고려하여 r = N - 2까지만 탐색하고, column은 2 ~ N - 1까지만 조사해보면 된다.

for (int tc = 1; tc <= T; tc++)
{
	input();

	MAXANS = -1;
	for (int r = 1; r <= N - 2; r++)
	{
		for (int c = 2; c <= N - 1; c++)
		{
			dessert[MAP[r][c]] = 1;
			DFS(1, r + 1, c + 1, r, c, 0);
			dessert[MAP[r][c]] = 0;
		}
	}

	printf("#%d %d\n", tc, MAXANS);
}

 

매번 DFS는 가던 방향을 계속 가거나, 시계 방향으로 방향을 변경할 수 있다.

 

종료 조건은 아래와 같다.

 

1) dir == 4 (방향을 네 번 바꾼 경우)

2) MAP의 범위를 벗어나는 경우

3) 이미 선택한 디저트를 먹은 경우

4) 무사히 도착한 경우 → MAXANS 갱신 (많이 먹은 디저트 수)

 

먹지 않은 디저트의 경우에만 가던 방향을 계속가서나 시계 방향으로 변경해주고,

그 외에 종료 조건을 넣어주면 DFS는 완성된다.

void DFS(int L, int R, int C, int sr, int sc, int dir)
{
	/* 1) dir == 4 (방향을 네 번 바꾼 경우) */
	if (dir == 4) return;

	/* 4) 무사히 도착한 경우 → MAXANS 갱신 */
	if (R == sr && C == sc)
	{
		if (MAXANS < L) MAXANS = L;
		return;
	}

	/* 2) MAP의 범위를 벗어나는 경우 */
	if (R > N || C > N || R < 1 || C < 1) return;

	if (dessert[MAP[R][C]] == 0)
	{
		dessert[MAP[R][C]] = 1;

		/* 현재 방향으로 진행 */
		DFS(L + 1, R + dr[dir], C + dc[dir], sr, sc, dir); 

		/* 시계 방향으로 진행 */
		DFS(L + 1, R + dr[dir + 1], C + dc[dir + 1], sr, sc, dir + 1);

		dessert[MAP[R][C]] = 0;
	}
	else /* 3) 이미 선택한 디저트를 먹은 경우 */
		return;
}

 

최종 코드는 아래와 같다.

#include <stdio.h>

#define MAX (25 + 5)

int T, N;
int MAP[MAX][MAX];

int dessert[100 + 20];
int MAXANS;

void input()
{
	scanf("%d", &N);
	for (int r = 1; r <= N; r++)
		for (int c = 1; c <= N; c++)
			scanf("%d", &MAP[r][c]);
}

/* 순서대로 오른쪽 아래, 왼쪽 아래, 왼쪽 위, 오른쪽 위 */
int dr[] = { 1, 1, -1, -1 };
int dc[] = { 1, -1, -1, 1 };

void DFS(int L, int R, int C, int sr, int sc, int dir)
{
	if (dir == 4) return;

	if (R == sr && C == sc)
	{
		if (MAXANS < L) MAXANS = L;
		return;
	}

	/* MAP의 범위를 벗어나는 경우 */
	if (R > N || C > N || R < 1 || C < 1) return;

	if (dessert[MAP[R][C]] == 0)
	{
		dessert[MAP[R][C]] = 1;

		/* 현재 방향으로 진행 */
		DFS(L + 1, R + dr[dir], C + dc[dir], sr, sc, dir); 

		/* 시계 방향으로 진행 */
		DFS(L + 1, R + dr[dir + 1], C + dc[dir + 1], sr, sc, dir + 1);

		dessert[MAP[R][C]] = 0;
	}
	else
		return;
}

int main(void)
{
	scanf("%d", &T);
	for (int tc = 1; tc <= T; tc++)
	{
		input();

		MAXANS = -1;
		for (int r = 1; r <= N - 2; r++)
		{
			for (int c = 2; c <= N - 1; c++)
			{
				dessert[MAP[r][c]] = 1;
				DFS(1, r + 1, c + 1, r, c, 0);
				dessert[MAP[r][c]] = 0;
			}
		}

		printf("#%d %d\n", tc, MAXANS);
	}

	return 0;
}
반응형

댓글