반응형
1. 문제 정의
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.
- 정사각형은 서로 겹치면 안 된다.
- 도형은 모두 연결되어 있어야 한다.
- 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.
정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.
아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.
테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.
테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.
-입력-
첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)
둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.
-출력-
첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.
2. 문제 접근
dfs로 접근하여 모든 경우를 완전탐색한다면 풀 수 있을 것 같다고 생각하여 그렇게 했다.
3. 문제 풀이
1. 각 입력값을 받는다.
2. dfs 함수를 실행한다.
4. 코드
package sw역량문제;
import java.io.*;
import java.util.StringTokenizer;
public class 테트로미노 {
static StringBuilder sb = new StringBuilder();
static int N, M, max_value;
static int[][] matrix;
static boolean[][] visited;
static int[][] dir = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
static void input() {
FastReader scan = new FastReader();
N = scan.nextInt();
M = scan.nextInt();
matrix = new int[N][M];
visited = new boolean[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
matrix[i][j] = scan.nextInt();
}
}
}
// Recursive Function (재귀 함수)
static void dfs(int k, int x, int y, int sum) {
if (k == 3) {
max_value = Math.max(max_value, sum);
} else {
for (int d = 0; d < 4; d++) {
int nx = x + dir[d][0];
int ny = y + dir[d][1];
// 배열 범위 벗어나면 패스
if (nx < 0 || ny < 0 || N <= nx || M <= ny) continue;
// 이미 방문한 경우 패스
if (visited[nx][ny]) continue;
if (k == 1) {
visited[nx][ny] = true;
dfs(k + 1, x, y, sum + matrix[nx][ny]);
visited[nx][ny] = false;
}
visited[nx][ny] = true;
dfs(k + 1, nx, ny, sum + matrix[nx][ny]);
visited[nx][ny] = false;
}
}
}
public static void main(String[] args) {
input();
max_value = Integer.MIN_VALUE;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
visited[i][j] = true;
dfs(0, i, j, matrix[i][j]);
visited[i][j] = false;
}
}
System.out.println(max_value);
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
5. 회고
테트로미노 중 ㅗ 모양은 일반 dfs로 모양을 만들기 힘들다. 그래서 중간에 한번 더 dfs 를 해주어 저 모양을 만들 수 있게 해주었다.
반응형
'코딩테스트 > 백준' 카테고리의 다른 글
14888번 - 연산자 끼워넣기 (1) | 2023.03.12 |
---|---|
14502번 - 연구소 (1) | 2023.03.12 |
13458번 - 시험 감독 (0) | 2023.03.04 |
3190번 - 뱀 (0) | 2023.03.04 |
12100번 - 2048 (Easy) (0) | 2023.03.04 |