본문 바로가기

Algorithm/CodeUp

[CodeUp_Java] Q1092 : [기초-종합] 함께 문제 푸는 날

반응형

안녕하세요! Plitche(플리체)입니다.
이번 포스팅의 주제는 Q1092 : [기초-종합] 함께 문제 푸는 날 (자바, JAVA)입니다.

intro

Question

문제 설명

입력

같은 날 동시에 가입한 인원 3명이 규칙적으로 방문하는,
방문 주기가 공백을 두고 입력된다. (단, 입력값은 100이하의 자연수이다.)

출력

n번째 수를 출력한다.

예시

  • 입력 : 3 7 9
  • 출력 : 63

Solution (풀이)

  •  풀이 1 : 메모리 14352, 시간 116
public class Answer1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();

        // 일반적인 수학공식인 공배수를 이용한 방법
        int common = 1;
        while(common%a!=0 || common%b!=0 || common%c!=0) {
            common++;    // 같이 다시 만날 날이 a,b,c와 나누어 떨이지지 않으면 1씩 증가시켜라
        }

        System.out.println(common);
        sc.close();
    }
}

 

  •  풀이 2 : 메모리 11200, 시간 69
public class Answer2 {
    // 3명이 다시 모두 함께 방문해 문제를 풀어보는 날(동시 가입/등업 후 며칠 후?)을 출력한다.

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        int c = Integer.parseInt(st.nextToken());

        // 일반적인 수학공식인 공배수를 이용한 방법
        int common = 1;
        while(common%a!=0 || common%b!=0 || common%c!=0) {
            common++;    // 같이 다시 만날 날이 a,b,c와 나누어 떨이지지 않으면 1씩 증가시켜라.
        }

        System.out.println(common);
        br.close();
    }
}

기본적으로 두 풀이는 동일한 형태이지만, Scanner를 사용한 1번 풀이가 확실히 성능이 떨어졌고, 한번에 연산을 하는 것이 더 좋다는 결과를 알 수 있다.

사용자로부터 여러 데이터를 입력을 받을 때에는 Scanner보다는 BufferedReader 등을 사용하는 것이 좋다.

 

  • 풀이 3 : 메모리 11196, 시간 67
public class Answer3 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        int c = Integer.parseInt(st.nextToken());

        // 1로 나누었을때는 어짜피 원래 숫자와 같기 때문에 공약수는 2로 시작
        int common = 2;

        // 공약수를 이용한 방법
        List<Integer> list = new ArrayList<Integer>(); // 공약수를 저장할 list
        while(common <= a || common <= b || common <= c) {
            boolean blA = false, blB = false, blC = false; // 먼저 모두 나누어 떨어지지 않았다고 가정

            if (a%common == 0) blA = true;
            if (b%common == 0) blB = true;
            if (c%common == 0) blC = true;

            // 2개 이상 false라면 공약수가 없다는 뜻임으로 넘어가기
            if ( (!blA && !blB) || (!blB && !blC) || (!blA && !blC) ) {
                common++;
                continue;
            }

            // 특정수의 공약수 일때 공약수를 list 저장하고 해당 숫자를 공약수로 나눈 값으로 바꾸기 
            if (blA && blB && blC) {
                a /= common;
                b /= common;
                c /= common;
                list.add(common);
            } else {
                if (blA && blB) {
                    a /= common;
                    b /= common;    
                    list.add(common);
                } else if (blB && blC) {
                    b /= common;
                    c /= common;    
                    list.add(common);
                } else if (blC && blA) {
                    a /= common;
                    c /= common;
                    list.add(common);
                }
            }
        }

        int result = a*b*c;
        // 리스트에서 공약수를 하나씩 꺼내어 결과에 곱하기
        for (int i=0; i<list.size(); i++) {
            result *= list.get(i);
        }

        System.out.print(result);
        br.close();
    }
}
  •  마지막 풀이가 가장 성능이 뛰어났으나, 비교적 복잡하고 중복되는 코드가 많아서 굳이? 라는 생각이 들기는 했습니다. 추후에 따로 메소드로 빼내어 간결하게 하는 방법으로 풀게 된다면 다시 공유 하겠습니다.

List(리스트)와 Array(배열)을 어떻게 구분해서 사용해야 할지는 지난번에 포스팅의 내용을 확인해보길 바랍니다.

반응형