📝 TIL

[TIL] 2주차 알고리즘 모의고사

오늘 ONEUL 2022. 11. 22. 22:32

✍ Today I Learned

 

 

알고리즘 모의고사

목요일 본 테스트를 앞두고,
오늘 알고리즘 모의고사를 치렀다.

주어진 시간은 2시간, 문제는 총 3문제. 모의고사는 이 중 1 문제만 풀면 된다.
조금 특별한 점은 풀이를 진행한 소스코드와 내 코드를 설명한 녹화본의 유튜브 링크를 제출해야 한다는 것이다.
시험 자체는 그다지 긴장되지 않았지만, 제출방법이 좀 복잡해서 혹시라도 차질이 생길까 걱정되었다.
다행히 어제 화면 녹화 연습도 한 번 해봤기 때문에(ㅋㅋㅋㅋ) 별 무리 없이 시험을 마칠 수 있었다.

내 목표는 주어진 2시간 안에 3문제를 모두 풀어내는 것이었는데,
아쉽게도 첫 번째 문제는 시간 안에 풀지 못했다.
시험장을 나와서 조원들과 함께 코드 리뷰를 하며 풀지 못했던 첫 번째 문제까지 올 클리어!
다음은 오늘 모의고사의 모든 문제와 내가 제출한 코드이다.

 

첫 번째 문제

 

문제를 분석해보자

  • 각 월의 마지막일이 담겨있는 배열 days를 선언한다. 이때 index로 접근해야 하므로 0번째는 0을 넣어준다.
  • 입력받은 월만큼 반복문을 돌면서 total 변수에 days 배열의 요소를 더해준다.
  • 입력받은 일과 98을 total 변수에 더해준다.
  • 만약 total 변수가 365 이상이라면 365를 빼준다.
  • 가장 짧은 달이 29일 이므로 total이 29 미만이 되기 직전까지 while문을 돌면서 total 변수에서 days 배열을 빼주고, 증감식으로 사용하는 monthNum 변수를 1씩 올려준다.
  • monthNum은 월로 출력, total은 일로 반환한다.
  • 포인트는 입력받은 날짜를 총일수로 변환하고 98일을 더해서 다시 n월 n일로 변환하는 것이다.

 

코드로 구현해보자

package algorithm.exam01;

public class Main {
    // int형 배열에 각 월의 마지막 일을 담아 생성
    // 입력 받은 월과 일을 총 일수로 변환
    // 총 일수에 + 98
    // 반복문으로 총 일수에서 배열의 일수를 빼줌
    // 카운트 되어 올라가는 monthNum이 월, 남은 total 값이 일
    
    public String solution(int month, int day) {
        int[] days = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int total = 0;
        int monthNum = 0;
        for (int i = 0; i < month; i++) {
            total += days[i];
        }
        total += day;
        total += 98;
        if (total > 365) {
            total -= 365;
        }
        while(total > 29) {
            total -= days[monthNum];
            monthNum++;
        }
        String answer = monthNum + "월 " + total + "일";
        return answer;
    }

    public static void main(String[] args) {
        Main method = new Main();
        System.out.println(method.solution(11, 27));
    }
}

 

 

두 번째 문제

 

문제를 분석해보자

  • for문을 돌면서 각 배열의 i번째끼리의 차를 정답 변수에 담는다.
  • 이때 체크아웃 배열인 arr2의 요소가 29 이상이면 21로 변경해준다.
  • 정답 변수를 반환한다.
  • 반복문과 조건문을 이용한 간단한 문제!

 

코드로 구현해보자

package algorithm.exam02;

public class Main {
    // for문을 돌면서 arr2의 i번째에서 arr1의 i번째의 시간을 뺌
    // 시간의 차이를 answer 변수에 담음
    // checkout 요소가 29를 넘어가면 21로 변경되도록 분기처리

    public int solution(int[] arr1, int[] arr2) {
        int answer = 0;
        for (int i = 0; i < arr1.length; i++) {
            if (arr2[i] >= 29) {
                arr2[i] = 21;
            }
            answer += arr2[i] - arr1[i];
        }
        return answer;
    }

    public static void main(String[] args) {
        Main method = new Main();
        int[] arr1 = {9, 9, 9, 9, 7, 9, 8};
        int[] arr2 = {23, 23, 30, 28, 30, 23, 23};
        System.out.println(method.solution(arr1, arr2));
    }
}

 

 

세 번째 문제

 

문제를 분석해보자

  • 소수란? 1보다 큰 자연수 중 1과 그 수 자기 자신만을 약수로 갖는 자연수를 의미한다.
  • 소수인지 아닌지 알기 위해서 입력받은 자연수의 제곱근보다 작은 자연수들로 모두 나눠본다. → Math.sqrt()
  • 입력받은 문자열을 split을 이용해서 String형 배열로 변환, 이후 int형 배열로 변환한다.
  • 반복문과 조건문을 통해 소수를 판별하고 소수인 것과 소수가 아닌 것을 각각 리스트에 담는다.
  • Collections.sort()를 이용하여 정렬한 후, 소수가 아닌 것의 0번째 요소와 소수인 것의 마지막 요소를 반환한다.
  • 이때 ArrayList에는 list[i] 이런 식의 접근이 아닌 get 메소드를 이용하여 접근해야 한다. → list.get(i)

 

코드로 구현해보자

package algorithm.exam03;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    // 소수가 담길 리스트와 소수가 아닌 값이 담길 리스트 생성
    // String으로 받은 값을 split으로 String 배열로 변환
    // 반복문을 통해 int형 배열로 변환
    // 반복문을 돌면서 2부터 자기 자신의 제곱근 까지의 수로 나누어서
    // 나머지가 0으로 떨어지는 약수가 3개 이상이면 소수가 아닌 리스트로 추가
    // 약수가 3개 미만이면 소수 리스트로 추가
    // 각 리스트를 정렬하고
    // 소수가 아닌 리스트의 첫 번째 값과 소수 리스트의 마지막 값을 출력

    public String solution(String s) {
        List<Integer> primeNums = new ArrayList<>();
        List<Integer> nonPirmeNums = new ArrayList<>();

        String[] strArr = s.split(" ");
        int[] intArr = new int[strArr.length];
        for (int i = 0; i < strArr.length; i++) {
            intArr[i] = Integer.parseInt(strArr[i]);
        }

        for (int i = 0; i < intArr.length; i++) {
            int count = 0;
            for (int j = 2; j <= Math.sqrt(intArr[i]); j++) {
                if (intArr[i] % j == 0) {
                    count++;
                }
            }
            if (count < 1) {
                primeNums.add(intArr[i]);
            } else {
                nonPirmeNums.add(intArr[i]);
            }
        }
        Collections.sort(primeNums);
        Collections.sort(nonPirmeNums);
        return nonPirmeNums.get(0) + " " + primeNums.get(primeNums.size() - 1);
    }

    public static void main(String[] args) {
        Main method = new Main();
        String s = "2 3 4 5";
        System.out.println(method.solution(s));
    }
}

 

 

 

오늘의 나는

실패가 두려워서 시작을 망설이는 스타일이었다.
그런 내가 알고리즘 주간에 들어서면서 '그냥 해보지 뭐!'라는 마인드로 무릎 깨지게 부딪히는 중이다.
새삼 내가 이렇게 문제를 풀어나가고 있는 게 조금 신기하기도. (물론 아직 한참 멀었지만)
에너지를 잃지 않고, 꾸준히 내 속도대로 달려 나가야겠다.
그러려면 기술 매니저님이 조언 주신대로 매일 산책도 좀 하고.. 밥도 잘 챙겨 먹고.. 잠도 잘 자야겠지..!
체력관리! 신경 쓰자!