본문 바로가기
알고리즘/Java 코딩 테스트 준비

[Java] 봉우리 수 구하기.

by Dev dreamer 2023. 2. 5.

N*N 격자판이 주어지며 격자의 가장자리는 0으로 초기화 되어있다.

 

 

🔍입력

 

첫줄에 자연수 N이 주어진다

 

두번째 줄부터 N 줄에 걸쳐 각 줄에 N 개의 자연수가 주어진다.(100이하 자연수)

 

🔍출력

 

봉우리의 개수를 출력하세요.

 

 

⚡ 입력예시

 

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 2

 

⚡출력예시

 

10

 

 

 

💡 1. 내 생각 및 풀이 과정 (1시간정도)


 

중요한 부분!!

이렇게 else가 없는 부분 즉 모든 부분의 만족하는 조건을 구하고자 할 때 내가 썼던 코드인데

이 부분의 코드를

 

 

그냥 이렇게 깔끔하게 바꿀수 있다.

 

 

 

처음에 문제를 봤을때 많이 막막했다. 이게 뭐지..

 

하지만 역시나 막상 조금씩 틀을 잡아가니까 금방했다.

 

입력부터 약간 다른 방식으로 받아야 하는데 격자의 가장자리가 0으로 초기화 되어있다.

 

즉 자연수 5를 받아서 5*5 의 정보를 입력받아도 5*5 가장자리에 한칸씩 더 있어야 한다.

 

즉 가장자리 까지 생각하면 7*7인 셈이다.

 

따라서 N*N 데이터를 저장하는 격자의 크기설정을 int[N+2][N+2] 로 설정했다.

 

배열의 빈공간에 데이터를 안넣어주면(초기화를 해주지 않으면) 그 자리에는 0이 들어가있다.

 

그리고 데이터를 집어 넣을때 for int i=1 ;i <num+1 범위로 설정해 가운데에 정보를 받도록 했다. j도 마찬가지이다.

 

이후 각 위 아래 양 옆 수보다 가장 커야 하므로

 

위 아래 양옆을 각각 비교해주고 원래의 수가 더 클때마다 cnt 를 1씩 더해줘서

 

총 4번 cnt가 더해진 1씩 커진 수. 즉 cnt가 4인 위 아래 양 옆보다 큰수 일 때 answer에 수를 하나씩 세도록 했다.

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	public int solution(int[][] a, int num) {
		int answer = 0;
		int cnt;
		for (int i = 1; i < num + 1; i++) {
			for (int j = 1; j < num + 1; j++) {
				cnt = 0;
				if (a[i][j] > a[i][j - 1]&& a[i][j] > a[i][j + 1] && a[i][j] > a[i - 1][j] && a[i][j] > a[i + 1][j]) {
					cnt++;
				}
				if (cnt == 1) {
					answer++;
				}
			}
		}

		return answer;
	}

	public static void main(String[] args) throws NumberFormatException, IOException {

		Main T = new Main();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int num = Integer.parseInt(br.readLine());
		int[][] arr = new int[num + 2][num + 2];

		StringTokenizer st;

		for (int i = 1; i < num + 1; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 1; j < num + 1; j++) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		System.out.println(T.solution(arr, num));
	}

};

 

 

 

 

💡 2. 강사님 풀이.


 강사님은 격자 외곽에 0 부분을 따로 만들어서 고려해주지 않고 그냥 존재하는 경우만 비교하게끔 코드를 짰다.

 

강사님은 if 문을 안쓰고 for 문을 하나 더 만들어서 각 위치에서 변화값을 배열마다 꺼내줬다.

 

이렇게 하는 이유는 대각선까지 8방향을 비교한다면 if 문을 8개를 만들어야 해서 엄청 복잡해진다.

 

이렇게 각 dx dy 변화값을 배열에 넣어서 순차적으로 배열에서 꺼내서 원하는 위치 값을 구할 수 있다.

 

int[] dx = {-1, 0 , 1, 0}

int[] dy = {0, 1 , 0, -1}

 

dx, dy를 배열에 맞게 순서대로 가져와 보면 xy 좌표로만 봤을 떄

{-1,0} {0,1} {1,0} {0,-1} 이다.

 

왼쪽 위쪽 오른쪽 아래 를 순차적으로 살펴보는 것이다.

 

x= i +dx[k]

y= j +dy[k]

 

강사님의 코드를 살펴보자.

 

각 배열의 위치를 표현해 줄 dx,dy 를 선언해주고

k라는 인수를 가진 for 를 하나 더 선언해서 nx ny 라는 인수를 구해 arr 과 비교를 해준다

 

❗ 중요 특징 1.

나는 cnt 를 세어서 4일때 즉 모든수가 다 큰경우를 체크하고자 했다.

이때는 보통 강사님 처럼 boolean 을 이용 하면 된다.

 

boolean 으로 false 로 한번만이라도 바뀌면 어차피 그 조건에 충족 못할꺼니까.

 

❗ 중요 특징 2.

 

오류나는 조건

 

알맞는 조건

 

 

이 두가지 경우를 살펴보자

 

강사님이 격자의 외부의 한칸을 더 추가하지 않고 해당 조건에서만 비교하고자 한다.

 

이때 nx 와 ny는 0보다 항상 크고 n보다는 작아야만 한다.

 

이때 arr[nx][ny] 조건이 먼저 들어가면 오류가 난다.

 

&&의 조건문은 앞에 조건문을 먼저 따지고 그 뒤에 값들을 조건문을 통과한 애들로 따져준다.

 

그래서 반드시 범위 같은 부분이 앞에오고 따지려는 실질적인 값들이 뒤에 가야 한다.

 

 

 

 


 

코테 관련해서 많이 부담스러웠는데 강의를 통해 푸는 방법들을 배우니 이 시간이 즐겁습니다.

진짜 기능하나하나 다양한 방법으로 잘 가르쳐주십니다.

출처 : 자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비 대시보드 - 인프런 | 강의 (inflearn.com)

댓글