Recent Posts
Link
250x250
오늘보다 더 나은 내일의 나에게_
자바 알고리즘 문제 풀이 Array Q10_봉우리 본문
728x90
설명
지도 정보가 N*N 격자판에 주어집니다. 각 격자에는 그 지역의 높이가 쓰여있습니다.
각 격자판의 숫자 중 자신의 상하좌우 숫자보다 큰 숫자는 봉우리 지역입니다. 봉우리 지역이 몇 개 있는 지 알아내는 프로그램을 작성하세요.
격자의 가장자리는 0으로 초기화되었다고 가정한다.
만약 N=5이고, 격자판의 숫자가 다음과 같다면 봉우리의 개수는 10개입니다.
입력
첫 줄에 자연수 N이 주어진다.(2 <=N <=50)
두 번째 줄부터 N 줄에 걸쳐 각 줄에 N개의 자연수가 주어진다. 각 자연수는 100을 넘지 않는다.
출력
봉우리의 개수를 출력하세요.
예시 입력1
예시 출력5
5 3 7 2 3
3 7 1 6 1
7 2 5 3 4
4 3 6 4 1
8 7 3 5 210
코드
내가 입력한 코드
더보기package Array; import java.util.Scanner; public class Q10 { public int solution(int n, int[][] arr) { int answer = 0; int[][] arr2 = new int[n+2][n+2]; //배열 0으로 채우기 for (int i = 0; i < n+2; i++) { arr2[0][i] = 0; arr2[n+1][i] = 0; for (int j = 1; j < n+1; j++) { arr[j][0] = 0; arr[j][n+1] = 0; } } //main에서 입력받은 arr배열을 arr2배열에 채우기 for (int i = 1; i < n+1; i++) { for (int j = 1; j < n+1; j++) { arr2[i][j] = arr[i-1][j-1]; } } //봉우리갯수 구하기 for (int i = 1; i < n+1; i++) { for (int j = 1; j < n+1; j++) { if(arr2[i][j] > arr2[i][j-1] && arr2[i][j] > arr2[i][j+1] && arr2[i][j] > arr2[i-1][j] && arr2[i][j] > arr2[i+1][j]) answer++; } } return answer; } public static void main(String[] args) { Q10 T = new Q10(); Scanner kb = new Scanner(System.in); int n = kb.nextInt(); int[][] arr = new int[n][n]; System.out.println(T.solution(n, arr)); } }
해설 코드import java.util.*; class Main { int[] dx={-1, 0, 1, 0}; int[] dy={0, 1, 0, -1}; public int solution(int n, int[][] arr){ int answer=0; for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ boolean flag=true; for(int k=0; k<4; k++){ int nx=i+dx[k]; int ny=j+dy[k]; if(nx>=0 && nx<n && ny>=0 && ny<n && arr[nx][ny]>=arr[i][j]){ flag=false; break; } } if(flag) answer++; } } return answer; } public static void main(String[] args){ Main T = new Main(); Scanner kb = new Scanner(System.in); int n=kb.nextInt(); int[][] arr=new int[n][n]; for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ arr[i][j]=kb.nextInt(); } } System.out.print(T.solution(n, arr)); } }
풀이 및 정리
역시 이번에도 채점 결과 런타임 에러... 문제 푸는 방식이 틀렸나 보다😭
해설 코드에서는 3중 for문을 사용하였다. 나는 입력받은 2차원 배열 주위에 0을 따로 채웠는데 그럴 필요가 없었다. 문제에서 구하는 값이 어떤 값을 중심으로 상하좌우 값들보다 큰 개수를 구하는 문제이다. 그렇다면 값 하나를 정해놓고 상하좌우 비교하는 알고리즘을 구해보면 문제를 풀 수 있다.
2중 for문이 작성됐다고 가정하고 2차원 배열의 변수를 arr이라고 하자.
i는 행, j는 열
arr [0][0]의 값은 5이고
상:0 => arr[i-1][j]
하:3 => arr[i+1][j]
좌:0 => arr[i][j-1]
우:3 => arr[i][j+1]
이런 식으로 반복이 될 수 있다. 그렇지만 arr[0][0]의 상:0 좌:0 값은 실제로 존재하지 않고 이를 무시한 체 코드를 작성하면 ArrayIndexOutOfBoundsException 예외가 발생해 이 또한 고려해서 코드를 작성해야 한다.
위와 같이 값하나 하나 비교를 할 때 arr[i-1][j], arr[i+1][j], arr[i][j+1], arr[i][j-1] 이런 식으로 조건문에서 비교를 한다면 가독성도 떨어지고 비효율적이다.
행과 열에 따른 들어갈 숫자를 배열로 만들어 주면 된다. 시계방향으로 값을 비교한다고 했을 때
상우하좌 비교할 값의 행의 인덱스를 보면 i-1, i, i+1, i인데 이걸 -1, 0, 1, 0 값이 반복된다고 볼 수 있고
열 또한 j, j-1, j, j+1인데 이걸 0, 1, 0,-1 값이 반복된다고 볼 수 있어 배열로 만들어 사용하면 훨씬 간편해진다.
int[] dx={-1, 0, 1, 0}; int[] dy={0, 1, 0, -1};
arr[i][j]에서 i에 행의 값인 dx배열의 0번째 -1와 i를 더해주고 j에는 열의 값인 dy배열의 0번째 인덱스 0을 j와 더해준다. 정리하면 arr[i+dx[k]][j+dy[k]]가 반복된다고 할 수 있다. (k의 값은 3중 for문의 변수 k)
arr[i+dx[k]][j+dy[k]]값을 이제 배열의 각 인덱스 값과 비교해주면 된다.
여기서 주의할 점이 존재하지 않은 인덱스와 비교하게 될 수 있어서 i+dx[k], j+dy[k]값은 반드시 0보다 커야 하고 처음에 입력한 정수 n보다는 작아야 한다. 그래야 ArrayIndexOutOfBoundsException가 발생하지 않는다.
728x90
'ALGORITHM > inflearn_javaAlgorithm' 카테고리의 다른 글
자바 알고리즘 문제 풀이 Array Q12_멘토링 (0) | 2022.02.22 |
---|---|
자바 알고리즘 문제 풀이 Array Q11_임시반장 정하기 (0) | 2022.02.19 |
자바 알고리즘 문제 풀이 Array Q09_격자판 최대합 (0) | 2022.02.15 |
자바 알고리즘 문제 풀이 Array Q08_등수구하기 (0) | 2022.02.13 |
자바 알고리즘 문제 풀이 Array Q07_점수계산 (0) | 2022.02.13 |
Comments