삼성 SW 역량테스트 기출문제인 테트로미노이다.
5가지의 테트로미노 중 하나를 놓았을 때 점수의 합이 최대인 경우 점수의 합을 출력하면 된다.
5가지의 테트로미노를 하나씩 놓아보면서 점수의 합이 최대일 때를 찾아내는 방법밖엔
없는 것 같았다.
테트로미노의 종류가 5개인데 회전도 가능하고 대칭도 가능하기 때문에
5가지의 경우만 검사해보면 되는 것이 아니라
꽤 많은 경우를 검사해봐야 한다.
물론 이렇게 구현하면 실행 속도가 가장 빠르지만
5가지의 테트로미노의 대칭, 회전 포함 모든 경우를 다 따로 검사하는 건
너무 코드가 길 것 같아서 DFS를 통한 백트래킹으로 모든 경우를 검사해보기로 했다.
DFS로 상하좌우를 탐색하다가 4번째까지 탐색했을 때
그 합의 최대값을 구하는 방법으로 진행했으나
계속해서 틀렸다.
분명 모든 경우를 다해본 것 같았지만
DFS로 탐색했을 때 검사하지 못하는 경우가 있었다.
바로 테트로미노의 모양이 ㅗ ㅜ ㅏ ㅓ 인 경우인데
DFS를 생각해보면 이미 거쳐왔던 길을 다시 돌아갈 수 없기 때문에
저 경우에는 탐색이 불가능한 것이었다.
그래서 원래 목적이었던 짧은 코드는 조금 멀어졌지만
위의 경우는 따로 탐색을 해줬다.
+모양의 점수를 구해서
하나씩 빼주며 max값을 갱신해주는 방식으로 구현했다.
실행 속도는 다른 분들에 비해 엄청나게 많이 차이 났지만
비교적 코드는 짧게 구현했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
public class Q14500 {
static int n;
static int m;
static int[][] a;
static int[] tx = {1, -1, 0, 0};
static int[] ty = {0, 0, 1, -1};
static int max = 0;
static boolean[] visited;
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(reader.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
a = new int[n][m];
visited = new boolean[n*m];
for(int i=0; i<n; i++) {
st = new StringTokenizer(reader.readLine());
for(int j=0; j<m; j++) {
a[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i=0; i<n*m; i++) {
int r = i/m;
int c = i%m;
visited[i] = true;
dfs(i, a[r][c], 0, visited);
getException(i);
Arrays.fill(visited, false);
}
System.out.println(max);
}
static void dfs(int idx, int sum, int cnt, boolean[] visited) {
if(cnt==3) {
max = Math.max(max, sum);
return;
}
int r = idx/m;
int c = idx%m;
visited[idx] = true;
for(int i=0; i<4; i++) {
if(r+tx[i]>=0 && r+tx[i]<n && c+ty[i]>=0 && c+ty[i]<m) {
if(!visited[(r+tx[i])*m+c+ty[i]]) {
dfs((r+tx[i])*m+c+ty[i], sum+a[r+tx[i]][c+ty[i]], cnt+1, visited);
}
}
}
visited[idx] = false;
}
static void getException(int idx) {
int r = idx/m;
int c= idx%m;
int sum = a[r][c];
int cnt = 0;
for(int i=0; i<4; i++) {
if(r+tx[i]>=0 && r+tx[i]<n && c+ty[i]>=0 && c+ty[i]<m) {
sum+= a[r+tx[i]][c+ty[i]];
cnt++;
}
}
if(cnt<3 || sum < max) return;
if(cnt==3) {
max = Math.max(max, sum);
} else {
for(int i=0; i<4; i++) {
}
}
}
}
|
'Algorithm' 카테고리의 다른 글
백준 17140 이차원 배열과 연산 Java (0) | 2019.09.17 |
---|---|
백준 15686 치킨 배달 Java (0) | 2019.09.13 |
2019 KAKAO 매칭 점수 Java (0) | 2019.09.06 |
백준 2293 동전 1 Java (0) | 2019.09.02 |
2019 KAKAO 후보키 Java (0) | 2019.08.27 |