Algorithm/Baekjoon(Java)

[백준/JAVA] 3052 : 나머지

비망노트 2022. 7. 16. 13:41
문제

두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다.

예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다.

수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다.

그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.

입력

첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다.

 

출력

첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다.

 

예제 입력 예제 출력
1
2
3
4
5
6
7
8
9
10
10
42
84
252
420
840
126
42
84
420
126
1
39
40
41
42
43
44
82
83
84
85
6

 

⭕ 풀이

import java.util.*;
import java.io.*;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[] numArr = new int[10];
        for(int i=0;i<numArr.length;i++){
            numArr[i] = Integer.parseInt(br.readLine())%42;
        }
        br.close();
        
        int diff = 10;
        for(int j = 0; j<numArr.length-1;j++){
            for(int x = j+1;x<numArr.length;x++){
                if(numArr[j] == numArr[x]){
                    diff--;
                    break;
                }
            }
        }
        System.out.print(diff);
    }
}

✅ 

우선 입력되는 수는 10개라고 했으니 42로 나눈나머지의 값들을 받을 길이 10짜리 numArr 배열을 생성해주었다.

한줄씩 입력받아 42로 나눈 나머지 값을 numArr의 각 인덱스로 초기화했다.

 

중복값이 허용되지않는 Set인터페이스를 사용했으면 풀이가 쉬워졌겠으나 

아직 인터페이스와 클래스를 제대로 다루지 못하기도하고 단계도 1차원배열단계이므로 최대한 배열로 풀어보려했다.

 

우선 diff = 10; 모든 수가 다른경우를 전제로 하고 for문을 작성했다.

 

예제 1번으로 예를 들자면

numArr에는 {1,2,3,4,5,6,7,8,9,10} 이 있는 상황이고 numArr[ j ] 과 numArr[ j+1 ] 을 비교한다.

여기서 안쪽for문을 j+1가 아닌 j 으로 초기화하고 바깥for문의 조건식도 numArr.length에서 -1을 하지않았다면

계속 j반복문과 x반복문은 동일한 값을 비교할테니 diff는 0이된다.

 

아무튼 이런식으로 바깥for문 j와 안쪽for문 x는 겹치는일이 없도록 for문을 작성해주고

같은 값이 발견될경우 중복값이 있다는 것이므로 diff를 1감소시킨 후 안쪽 for문을 탈출한다.

 

마지막엔 중복값이 있던 수 만큼 감소된 diff 를 출력한다.

        int cnt;
        int diff = 10;
        for(int j = 0; j<numArr.length-1;j++){
            cnt = 0;
            for(int x = j+1;x<numArr.length;x++){
                if(numArr[j] == numArr[x]){
                    cnt++;
                    break;
                }
            }
            if(cnt>0){diff--;}
        }
        System.out.print(diff);

처음에는 이런식으로 변수 cnt를 사용해주었다가 다시 보니 굳이 필요없을것같아서 ⭕ 풀이 의 코드처럼 작성했다.

 

그런데 나의 코드는 답은 맞지만 비효율적인 코드인것같았다.

이렇게 말로 설명하려해도 복잡해보였고, 때문에 다른분들의 코드를 보던중

Set인터페이스를 사용하지 않은 풀이중에 깔끔해보이는 코드가 있어 가져왔다.

 

✅  다른분의 풀이

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[] remainder = new int[42];
        for (int i = 0; i < 10; i++) {
            remainder[Integer.parseInt(br.readLine()) % 42]++;
        }
        
        int count = 0;
        for (int i = 0; i < remainder.length; i++) {
            if (remainder[i] > 0) {
                count++;
            }
        }
        System.out.println(count);
        br.close();
    }
}

%42 니까 나머지는 0~41 총 42개의 경우의수가 나올 수 있으므로

길이42의 배열을 생성해주고 한줄씩 입력받은 값을 따로 저장하지않고

그 값의 인덱스를 증가시켰다.

즉 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.....} 42길이의 0으로 초기화된 배열에

42로 나눈 나머지의 값을 인덱스로 넣어 증가시켰고

그 배열을 밑의 for문에서 각인덱스의값이 0 보다 크다면, 즉 증가되었다면 count를 증가시키는 코드였다.

 

 

 

-출처

https://www.acmicpc.net/problem/3052