백준 18430[자바] java 무기 공학
문제 링크: https://www.acmicpc.net/
Baekjoon Online Judge
Baekjoon Online Judge 프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳입니다.
www.acmicpc.net
▶문제
공학자 길동이는 외부의 침략으로부터 마을을 지킬 수 있는 부메랑 무기를 개발하는 공학자다. 길동이는 부메랑 제작을 위한 고급 나무 재료를 구했다. 이 나무 재료는 NxM크기의 직사각형 형태이며 나무 재료의 부위마다 그 강도가 조금씩 다르다.
예를 들어 나무 재료의 크기가 2x3일 때는 다음과 같이 총 6칸으로 구성된다.
길동이는 이처럼 넓은 사각형 형태의 나무 재료를 잘라서 여러 개의 부메랑을 만들고자 한다. 그리고 부메랑은 항상 3칸을 차지하는 ‘ㄱ’ 모양으로 만들어야 한다. 따라서 부메랑의 가능한 모양은 다음과 같이 총 4가지다.
이때 부메랑의 중심이 되는 칸은 강도의 영향을 2배로 받는다. 위 그림에서 노란색으로 칠한 부분이 ‘중심이 되는 칸’이다. 예를 들어 앞선 예시에서는 다음과 같이 2개의 부메랑을 만들 수 있으며, 이때 만들어지는 부메랑들의 강도의 합은 46으로 이보다 강도의 합이 높아지는 경우는 없다.
또한 나무 재료의 특정 위치는 아예 사용하지 않아도 괜찮다. 예를 들어 앞선 예시에서 다음과 같이 1개의 부메랑만을 만들어도 괜찮다. 다만, 이렇게 만들게 되면 부메랑들의 강도의 합이 18이 되기 때문에 비효율적이다.
나무 재료의 형태와 각 칸의 강도가 주어졌을 때, 길동이가 만들 수 있는 부메랑들의 강도 합의 최댓값을 출력하는 프로그램을 작성하시오.
▶입력
첫째 줄에는 길동이가 가지고 있는 나무 재료의 세로, 가로 크기를 의미하는 두 자연수 N, M이 주어진다. (1 ≤ N, M ≤ 5) 다음 N개의 줄에 걸쳐서, 매 줄마다 나무 재료의 각 위치의 강도를 나타내는 M개의 자연수 K가 공백을 기준으로 구분되어 주어진다. (1 ≤ K ≤ 100)
▶출력
첫째 줄에 길동이가 만들 수 있는 부메랑들의 강도 합의 최댓값을 출력한다.
단, 나무 재료의 크기가 작아서 부메랑을 하나도 만들 수 없는 경우는 0을 출력한다.
▶해설
N과M의 범위가 크지 않으므로 완전 탐색을 활용해서 풀 수 있습니다. 조건을 살펴보겠습니다.
1. ㄱ자 모양을 돌린 것의 칸에 해당하는 값을 얻는다. 중간 칸은 *2이다.
2. ㄱ자 모양이 벗어나면, 진행할 수 없다.
완전 탐색을 진행할 때 중요한 점은 언제 탐색을 끝마치고, 큰 값을 비교할지입니다.
0,0 ~ N*M까지 모든 지점을 들려야 합니다.
따라서 index=0 부터 시작하고, index = N*M일 때 끝마칩니다.
y = index / m
x = index % m 로 행과 열을 구할 수 있습니다.
if(index ==n*m){
result = Math.max(result, temp);
return;
}
이제 해당 지점을 방문한지 살펴보고 ㄱ모양을 돌려가며 진행했을 때 만족하는지 확인하면 됩니다. 예시를 보겠습니다.
y, x를 방문하지 않았고, ㄱ모양일 때 y+1 <n이고, x-1>=0을 체크해주고, 해당 지점들을 방문했는지 확인합니다.
그리고 방문하지 않았다면, 방문 체크를 해주고, index를 1 더하고 탐색을 마저 진행합니다. 탐색이 끝났다면 원래대로 방문하지 않은 false로 돌려줍니다.
if(!visit[y][x]){
if(y+1<n && x-1>=0 && !visit[y+1][x] && !visit[y][x-1]){
visit[y][x]=true;
visit[y+1][x]=true;
visit[y][x-1]=true;
dfs(index+1, temp+map[y+1][x]+map[y][x-1]+(map[y][x]*2));
visit[y][x]=false;
visit[y+1][x]=false;
visit[y][x-1]=false;
}
}
이렇게 해당 지점에서 방문 했을 때 경우가 있다면 방문할 수 있음에도 불구하고, 방문하지 않는 경우도 체크해야 합니다.
private static void dfs(int index, int temp){
// 중략
if(!visit[y][x]){
// 중략
}
dfs(index+1, temp);
}
전체 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
static int n,m;
static int[][]map;
static boolean[][]visit;
static int result;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
map = new int[n][m];
visit = new boolean[n][m];
for(int i=0; i<n; i++){
String[] s1 = br.readLine().split(" ");
for(int j=0; j<m; j++){
map[i][j] = Integer.parseInt(s1[j]);
}
}
dfs(0,0);
System.out.println(result);
}
private static void dfs(int index, int temp){
if(index ==n*m){
result = Math.max(result, temp);
return;
}
int y = index/m;
int x = index%m;
if(!visit[y][x]){
if(y+1<n && x-1>=0 && !visit[y+1][x] && !visit[y][x-1]){
visit[y][x]=true;
visit[y+1][x]=true;
visit[y][x-1]=true;
dfs(index+1, temp+map[y+1][x]+map[y][x-1]+(map[y][x]*2));
visit[y][x]=false;
visit[y+1][x]=false;
visit[y][x-1]=false;
}
if(y+1<n && x+1<m && !visit[y+1][x] && !visit[y][x+1]){
visit[y][x]=true;
visit[y+1][x]=true;
visit[y][x+1]=true;
dfs(index+1, temp+map[y+1][x]+map[y][x+1]+(map[y][x]*2));
visit[y][x]=false;
visit[y+1][x]=false;
visit[y][x+1]=false;
}
if(y-1>=0 && x-1>=0 && !visit[y-1][x] && !visit[y][x-1]){
visit[y][x]=true;
visit[y-1][x]=true;
visit[y][x-1]=true;
dfs(index+1, temp+map[y-1][x]+map[y][x-1]+(map[y][x]*2));
visit[y][x]=false;
visit[y-1][x]=false;
visit[y][x-1]=false;
}
if(y-1>=0 && x+1<m && !visit[y-1][x] && !visit[y][x+1]){
visit[y][x]=true;
visit[y-1][x]=true;
visit[y][x+1]=true;
dfs(index+1, temp+map[y-1][x]+map[y][x+1]+(map[y][x]*2));
visit[y][x]=false;
visit[y-1][x]=false;
visit[y][x+1]=false;
}
}
dfs(index+1, temp);
}
}
'Alogorithm' 카테고리의 다른 글
백준 2469[자바] java 사다리 타기 (0) | 2022.05.30 |
---|---|
백준 3067[자바] java Coins (0) | 2022.05.29 |
백준 1174[자바] java 줄어드는 수 (0) | 2022.05.21 |
백준 21318[자바] java 피아노 체조 (0) | 2022.05.20 |
백준 22866[자바] java 탑 보기 (0) | 2022.05.17 |
댓글
이 글 공유하기
다른 글
-
백준 2469[자바] java 사다리 타기
백준 2469[자바] java 사다리 타기
2022.05.30 -
백준 3067[자바] java Coins
백준 3067[자바] java Coins
2022.05.29 -
백준 1174[자바] java 줄어드는 수
백준 1174[자바] java 줄어드는 수
2022.05.21 -
백준 21318[자바] java 피아노 체조
백준 21318[자바] java 피아노 체조
2022.05.20