[ Programmers ] 땅따먹기 (Java)

ma.caron_g·2021년 12월 10일
0

Lv.2 - Programmers

목록 보기
8/14
post-thumbnail

1. Problem 📃

[ 땅따먹기 ]

https://programmers.co.kr/learn/courses/30/lessons/12913


[ 문제 설명 ]

문제 설명
땅따먹기 게임을 하려고 합니다.
땅따먹기 게임의 땅(land)은 총 N행 4열로 이루어져 있고, 모든 칸에는 점수가 쓰여 있습니다.
1행부터 땅을 밟으며 한 행씩 내려올 때, 각 행의 4칸 중 한 칸만 밟으면서 내려와야 합니다.
단, 땅따먹기 게임에는 한 행씩 내려올 때, 같은 열을 연속해서 밟을 수 없는 특수 규칙이 있습니다.

예를 들면,

| 1 | 2 | 3 | 5 |

| 5 | 6 | 7 | 8 |

| 4 | 3 | 2 | 1 |

로 땅이 주어졌다면, 1행에서 네번째 칸 (5)를 밟았으면, 2행의 네번째 칸 (8)은 밟을 수 없습니다.

마지막 행까지 모두 내려왔을 때, 얻을 수 있는 점수의 최대값을 return하는 solution 함수를 완성해 주세요.
위 예의 경우, 1행의 네번째 칸 (5), 2행의 세번째 칸 (7), 3행의 첫번째 칸 (4) 땅을 밟아 16점이 최고점이 되므로 16을 return 하면 됩니다.


2. Constraint 🔗

[ 제한 사항 ]

  • 행의 개수 N : 100,000 이하의 자연수
  • 열의 개수는 4개이고, 땅(land)은 2차원 배열로 주어집니다.
  • 점수 : 100 이하의 자연수

3. Example 📚

[ 입출력 예시 ]

landanswer
[[1,2,3,5],[5,6,7,8],[4,3,2,1]]16
[[4, 3, 2, 1], [2, 2, 2, 1], [6, 6, 6, 4], [8, 7, 6, 5]]20

4. Solution 🔑

[ 잘못된 접근 ]

문제를 보고 열(Row)이 겹치지 않게 각 행마다 최댓값을 더해나가면 풀 줄 알았다.
대신 행(i)에 max값이 여러개 있을 경우 다음 행(i+1)은 자유롭게 이전 열에 신경쓰지 않고 자유롭게 고를 수 있도록 만들었지만 접근이 잘못 되었다.
이럴 경우 가장 큰 값을 고르고 열에 제한을 주었을 때, 다음 행 같은 열에 큰 수가 있음에도 고르지 못하는 경우가 발생한다.


[ 다른 사람 풀이를 보고 푼 코드 ]

  1. 기존에 입력 받은 배열(land)에 본인의 행과 그 이전 또는 다음 행 다른 열에 존재하는 값들의 합 중 가장 큰 경우의 수를 골라 그 행의 열에 최댓값들을 누적시킨다.

  2. 이를 행의 길이 끝까지 반복하여 같은 열이 아닌 다른 열들의 합을 최종적으로 구한다.
    마지막 행을 나타낼 배열(temp)를 선언하고, Arrays.sort(배열명);을 하여 최댓값을 마지막 인덱스로 보낸다.

  3. answer에 마지막 인덱스 값을 담아서 answer을 반환한다.

5. Code 💻

[ 잘못된 접근으로 풀어 본 코드 ]

class Solution {
	//가장 큰 수를 뽑았을 때 가장 큰 수의 열.
	static int preRow = -1;
	//자유롭게 선택 가능한지 여부(전 행에 최댓값이 여러개 존재하면 다음 행은 자유롭게 선택 가능)
	static boolean free = true;
	//행에서 최댓값을 찾아줄 변수.
	
	public int Search(int[] arr, int Row) {
		int max = 0;
		int temp = 0;
//		System.out.println("이전 열은 : " + preRow);
		if(free == true) {
			for(int i=0; i<4; i++) {
				if(arr[i] == max) {
					free = true;
				}
				else if(arr[i] > max) {
					max = arr[i];
					free = false;
					temp = i;
				}
			}
		}
		else {
			for(int i=0; i<4; i++) {
				if(arr[i] == max) {
					free = true;
				}
				if(arr[i] > max && preRow != i) {
					max = arr[i];
					temp = i;
//					System.out.print(max + " ");
//					System.out.println();
				}
			}
		}
		preRow = temp;
		
		return max;
	}
    int solution(int[][] land) {
        int answer = 0;

        for(int i=0; i<land.length; i++) {
//        	System.out.println("자유롭게 선택 가능한가 : " + free);
        	answer += Search(land[i], preRow);
//        	System.out.println(answer);
        }

        return answer;
    }
}

[ 다른 사람의 풀이를 보고 푼 코드 ]

import java.util.Arrays;

class Solution {
    int solution(int[][] land) {
        int answer = 0;
        
        for(int i=1; i<land.length; i++) {
        	land[i][0] += Math.max(Math.max(land[i-1][1],  land[i-1][2]), land[i-1][3]);
        	land[i][1] += Math.max(Math.max(land[i-1][0],  land[i-1][2]), land[i-1][3]);
        	land[i][2] += Math.max(Math.max(land[i-1][0],  land[i-1][1]), land[i-1][3]);
        	land[i][3] += Math.max(Math.max(land[i-1][0],  land[i-1][1]), land[i-1][2]);
        }

        int[] temp = land[land.length - 1];
        Arrays.sort(temp);
        
        answer = temp[temp.length - 1];
        
        return answer;
    }
}

6. Growth 🍄

행 마다 이전 행에서 선택한 값과 같은 열이 아닌 수들의 합의 최댓값들을 구하면서 배열 을 탐색할 수 있는 방법을 새롭게 배워간다.

아직 많이 부족하다고 느꼈고, 간략한 길이의 코드로 문제의 내용을 표현 할 수 있었음에 놀 랐다.
좀 더 생각을 깊이 해 볼 필요가 있음을 느끼는 문제였다..
profile
다른 사람이 만든 것을 소비하는 활동보다, 내가 생산적인 활동을 하는 시간이 더 많도록 생활화 하자.

0개의 댓글