[白俊14500]トロミノ-Java
![](https://s1.md5.ltd/image/bdda40b59fb58dd4d1af2e5db1ab5dc4.png)
![](https://s1.md5.ltd/image/b23abc0fd964639c4accee2bf771d900.png)
すべての場合、まず検索するのは個数で、それから最大値を求めます.
DFSで解決すべきだと思います.
しかし、どのように接近するか分からないので、ヒントを参考にしました.
結論として、「ㅜ」以外の図形は再帰呼び出しですべての形式で表示できる
すなわち,始点から上,下,左,右を観察し,値があれば再帰を呼び出し,4回呼び出すことで4つの整数の総和を求めることができる.
また、「ㅜ」パターンの場合は、上、下、左、右を観察し、値があれば合計後、上、下、左、右ともに値があれば、最後に最低値を落とせばよい.
次のコードで実現しました.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
static int result = Integer.MIN_VALUE;
static int N;
static int M;
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, -1, 0, 1};
static int[][] irr;
static boolean[][] visited;
static void dfs(int y, int x, int cnt, int pos) {
// 도형이 완성되면 최대값 구하고 리턴
if(cnt == 4) {
result = Math.max(result, pos);
return;
}
for(int i = 0; i < 4; i++) {
int nexti = y + dy[i];
int nextj = x + dx[i];
// 종이 범위에 벗어나면 다음 방향 진행
if(nexti < 0 || nextj < 0 || nexti >= N || nextj >= M) {
continue;
}
// 현재 방문한 위치인지 확인
if(visited[nexti][nextj]) {
continue;
}
visited[nexti][nextj] = true;
dfs(nexti, nextj, cnt +1, pos + irr[nexti][nextj]);
visited[nexti][nextj] = false;
}
}
// 'ㅜ'도형에서 최대값 구하기
static void excep(int y, int x) {
// wing은 상,하,좌,우
int wing = 4;
int min = Integer.MAX_VALUE;
int sum = irr[y][x];
for(int i = 0; i < 4; i++) {
int nexti = y + dy[i];
int nextj = x + dx[i];
// wing이 2개이하면 'ㅜ'도형이 아님
if(wing <= 2) {
return;
}
// 종이 범위에 벗어난 경우 잘린 도형 확인
if(nexti < 0 || nextj < 0 || nexti >= N || nextj >= M) {
wing--;
continue;
}
min = Math.min(min, irr[nexti][nextj]);
sum = sum + irr[nexti][nextj];
}
// 상,하,좌,우 모두 값 있을시, 그 중 최소값을 뺴준다
if(wing == 4) {
sum = sum - min;
}
result = Math.max(result, sum);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
String[] arr = str.split(" ");
N = Integer.parseInt(arr[0]);
M = Integer.parseInt(arr[1]);
irr = new int[N][M];
visited = new boolean[N][M];
for(int i = 0; i < N; i++) {
String[] nrr = br.readLine().split(" ");
for(int j = 0; j < M; j++) {
irr[i][j] = Integer.parseInt(nrr[j]);
}
}
// 종이판 (0,0) 부터 탐색 시작
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
dfs(i, j, 0, 0);
excep(i, j);
}
}
System.out.print(result);
}
}
Reference
この問題について([白俊14500]トロミノ-Java), 我々は、より多くの情報をここで見つけました https://velog.io/@hyeokjinon/백준-14500-테트로미노-Javaテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol