[백준/Java] 14500 - 테트로미노

2025. 9. 19. 14:13·코딩테스트/백준

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

문제


풀이

테트로미노는 연속된 4개의 칸이라는 공통점이 있다

따라서 특정 칸에서 시작하여 깊이가 4가 될 때까지 탐색하는 DFS를 활용할 수 있다

주의할 점은 `'ㅗ', 'ㅜ', 'ㅏ', 'ㅓ'` 모양은 한 칸에서 시작해서 상하좌우로만 4번 움직이는 DFS 경로로는 만들 수 없다

그래서 저 모양을 제외한 모양은 DFS로 탐색하고 'ㅗ' 모양은 따로 구현해준다

 

DFS

깊이가 4가 될 때까지 재귀 호출한다

상하좌우를 탐색하면서 방문하지 않은 곳을 만나면 깊이를 하나 더하고 현재까지 합에 새로운 배열 값을 더해 재귀 호출하면서 최댓값을 갱신해준다

 

'ㅗ' 모양 처리

(x, y)를 중심으로 하는 상하좌우 십자 모양을 탐색하고

십자 모양이 만들어질 수 있다면 십자의 숫자를 모두 더한 후 날개 값 중 가장 작은 값을 뺀다면 해당 모양의 최댓값이 될 것이다

자세한건 코드를 보자

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;


public class Main {

	static int N, M;
	static int[][] arr; // 입력 배열
	static boolean[][] visited; // 방문 처리
	static int[] dx = {-1, 1, 0, 0}; // 상하
	static int[] dy = {0, 0, -1, 1}; // 좌우

	static int max; // 결과값

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();

		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		arr = new int[N][M];
		visited = new boolean[N][M];

		// 배열 입력
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < M; j++) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				visited[i][j] = true; // 시작점 방문 처리
				dfs(i, j, 1, arr[i][j]); // 시작점에서 dfs 호출, depth=1, sum=현재 칸의 값
				visited[i][j] = false; // 다음 탐색을 위해 false 처리
				oh(i, j); // 'ㅗ' 모양은 dfs 경로로 만들 수 없기 때문에 따로 처리
			}
		}

		System.out.println(max);

		br.close();
	}

	static void dfs(int x, int y, int depth, int sum) {
		// depth가 4가 되면 최댓값을 갱신하고 리턴
		if (depth == 4) {
			max = Math.max(max, sum);
			return;
		}

		for (int i = 0; i < 4; i++) {
			// 상하좌우 탐색
			int nx = x + dx[i];
			int ny = y + dy[i];

			// 배열 범위 안에 있고
			if (nx >= 0 && nx < N && ny >= 0 && ny < M) {
				// 방문하지 않았다면
				if (!visited[nx][ny]) {
					visited[nx][ny] = true; // 방문 처리
					// depth + 1, sum에 배열 값을 더해서 재귀 호출
					dfs(nx, ny, depth + 1, sum + arr[nx][ny]);
					visited[nx][ny] = false; // 다음 탐색을 위해 false 처리
				}
			}
		}
	}

	static void oh(int x, int y) {
		// (x, y)가 중심점이 되는 4가지 'ㅗ' 모양 확인
		int wingCount = 4;
		int sum = arr[x][y];
		int minWing = 1001;

		for (int i = 0; i < 4; i++) {
			// 상하좌우 확인
			int nx = x + dx[i];
			int ny = y + dy[i];

			// 날개가 범위를 벗어나면
			if (nx < 0 || nx >= N || ny < 0 || ny >= M) {
				wingCount--; // 날개 카운트 -1
				continue;
			}

			sum += arr[nx][ny]; // 모든 날개를 다 더함
			minWing = Math.min(minWing, arr[nx][ny]); // 날개 중 최소를 찾음
		}

		// 날개가 3개 미만이면 'ㅗ' 모양 불가
		if (wingCount < 3) {
			return;
		} else if (wingCount == 4) { // 날개가 4개면
			sum -= minWing; // 그 중 가장 작은 날개를 하나 빼면 그것이 'ㅗ' 모양 중 가장 큰 수
		}

		max = Math.max(max, sum); // 최댓값 갱신
	}

}

결과

'코딩테스트/백준' 카테고리의 다른 글
  • [백준/Java] 1107 - 리모컨
  • [백준/Java] 15663 - N과 M (9)
  • [백준/Java] 11725 - 트리의 부모 찾기
  • [백준/Java] 9019 - DSLR
KDH.dev
KDH.dev
  • KDH.dev
    CodingHard
    KDH.dev
  • 전체
    오늘
    어제
    • 전체글 (83)
      • 코딩테스트 (74)
        • 프로그래머스 (13)
        • 백준 (61)
      • CS (5)
        • 네트워크 (5)
      • Spring (1)
      • Java (3)
        • 자료구조 (3)
        • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    16935
    자료구조
    14940
    11660
    멀티캠퍼스it부트캠프
    부트캠프후기
    18111
    17626
    프로그래머스
    21736
    코딩테스트
    자바
    CS
    백준
    네트워크
    30804
    프로그래머스 Lv.0
    5525
    13913
    [LG유플러스] 유레카 백엔드 개발자
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
KDH.dev
[백준/Java] 14500 - 테트로미노
상단으로

티스토리툴바