Study/Algorithm

[구름] 근묵자흑

728x90

❗❗ 해당 문제는 JAVA 로 풀었습니다.

level.goorm.io/exam/47881/근묵자흑/quiz/1

문제

근묵자흑이라는 말이 있습니다. 검은 먹을 가까이 하면 검어진다는 뜻이죠. 이는 좋지 못한 사람과 가까이 하면 악에 물들게 된다고 해석할 수 있습니다. 이는 사람 뿐만 아니라 숫자도 마찬가지입니다. 여러 숫자들을 한 곳에 모아두면 시간이 흘러 모든 숫자가 그 중 가장 작은 수에 맞춰 변하게 됩니다.

 

현재 1부터 N까지의 정수가 한 번씩 등장하는 길이 N의 수열이 있습니다. 여기서 당신은 연속된 K개의 정수를 골라서 한 곳에 잠시 모아둘 수 있습니다. 시간이 지나면 당신이 고른 K개의 정수들은 K개 중 가장 작은 정수가 됩니다. 이 시간은 고려하지 않습니다. 여기서 이 수열을 모두 같은 수로 만들고자 할 때 최소 몇 번 골라야 하는지 구해주세요.

 

예를 들어 4개의 수가 [2, 3, 1, 4]와 같이 있고 K=3일 때, [2, 3, 1, 4]을 고르게 되면 세 수는 2, 3, 1 중 가장 작은 수인 1로 변하게 됩니다. 이후 [1, 1, 1, 4]가 됩니다. 아직 4가 남아있으니 [1, 1, 1, 4]를 고르게 되면 [1, 1, 1, 1]이 되고 총 2번만에 모두 같은 수로 만드는 데 성공합니다.

 

입력 형식

첫 줄에 공백으로 구분된 두 정수 N, K가 차례로 주어진다.
- N은 수열의 길이를 나타내는 2 이상 10만 이하의 자연수다.
- K는 한 번에 연속적으로 골라야 하는 정수의 개수를 나타내는 2 이상 N 이하의 자연수다.

두 번째 줄에는 공백으로 구분된 N개의 정수가 주어진다.
- 각 정수는 1부터 N까지의 정수 중 하나이며, 같은 정수가 두 번 이상 나타나지 않는다.

출력 형식

주어진 수열을 모두 같은 수로 만들고자 할 때 골라야 하는 최소 횟수를 출력한다.

 

예시

 

  • 입출력 형식을 잘 지켜주세요.

 

문제

import java.io.*;
class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String input = br.readLine();
		System.out.println("Hello Goorm! Your input is " + input);
	}
}

 

 


내 풀이

import java.io.*;
import java.util.Arrays;
class Main {
	 public static void main(String[] args) throws Exception {
	        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	        String input = br.readLine();

	        String[] inputArr=input.split(" ");
	        int n= Integer.parseInt(inputArr[0]);
	        int k= Integer.parseInt(inputArr[1]);

	        //n배열
	        int nArr[]=new int[n];
	        for(int i=0;i<inputArr.length-2;i++){
	            nArr[i]=Integer.parseInt(inputArr[i+2]);
	        }

	        Arrays.sort(nArr); //먼저 오름차순으로 정렬
	        int a=0;
	        int count=0;
	        while(true){
	            for(int x=a;x<k;x++){
	                nArr[x]=nArr[a];
	            }
	            a+=k-1;
	            count++;
	            if(a>=n-1) break;
	        }
	        System.out.println(count);
	    }

 

  • 두 정수 N과 K가 차례로 주어짐 = 공백으로 구분
  • 두 번째 줄에는 공백으로 구분된 N개의 정수가 주어짐

 

문제를 확인하면 N K {1 ~ N까지 순서는 랜덤} 이 형식이 String input이 된다.

즉, 예시를 보며 설명해주자면 첫번째 예시에서 입력 형식이 4(N) 3(K) 2 3 1 4 이 순서대로가 된다.

공백으로 구분한다는 점을 체크하고, String input 을 문자열 배열로 만들어 준다. input.split(" ");

그리고 n과 k를 꺼내야하고 문제를 확인해보면, int n 은 무조건 inputArr[0], int k는 무조건 inputArr[1] 

 

그 후 {1 ~ N까지 순서는 랜덤} 이 배열을 정수 배열로 뽑아와야 한다.

inputArr.length 는 N, K, {1~N까지 숫자들} 로 N+2개 가 되므로 for문을 inputArr.length-2 까지 돌려주었으며

{1 ~ N까지 숫자들} 의 첫 시작은 index가 2번째부터 시작이므로 i+2로 지정

 

최소 횟수를 구하는것 이므로 nArr배열을 오름차순 정렬 해준다.

그리고 1(최소 숫자) 로 만들어줄 시작지점 변수 a, 횟수 찾을 변수 count를 각각 0으로 지정해주고

(배열의 index는 0부터 시작하므로 int a=0)

 

while문으로 무한루프를 만들어서

a=0부터 시작해서 k개 만큼 숫자 1 (nArr[0]) 로 만들어 주는 for문을 만들어 준다.

그 후 a는 k-1 만큼 증가해야하므로 a+=k-1;

횟수도 증가시켜준다. count++;

단, 배열의 index는 0부터 시작이고 숫자 n의 index는 n-1.. 그러므로 a>=n-1 이면 무한루프를 빠져나가준다.

 

 


 

스코페 모의테스트에 근묵자흑 나왔었는데..

그 당시에는 혼자 포트폴리오 제작하느라 머리가 어질어질해서 문제 확인만 하고 바로 덮었었는데....ㅎㅎ.. 막상 푸니까 별거 아니였던 ..... 

여러가지 답안을 확인하고 싶은데 요즘 몸 상태가 별로라서.. 컨디션 좋아질때 찾아봐야겠다 😂😂