본문 바로가기

항해99/시험 리뷰

[항해99] 기초 프로그래밍2 시험 리뷰

오늘은 기초 프래그래밍2 시험이 있었다.

알고리즘 문제를 해결하는 시험이였는데 생각보다 어려워서 고생했다.ㅠㅠ

상중하 문제가 있었고 각 3,2,1점이였다. 3점 이상이 통과여서 일단 시험에 패스하는 것을 목표로 코드를 짰다.

 

1번 문제 : 서현이의 잔돈 계산기

 

사실 이 문제는 보자마자 쉽게 해결했다.

 

작성코드

public class test {
    public static void main(String[] args) {


        test method = new test();
        int num = 160; // 가격
        System.out.println(method.solution(num));


    }

    public int solution(int num) {
        //int price = 900;
        int pay = 1000; // 돈
        int change = pay - num; // 거스름돈

        int a = change / 500;
        change %= 500;
        int b = change / 100;
        change %= 100;
        int c = change / 50;
        change %= 50;
        int d = change / 10;

        int e = a + b + c + d;

        return e;

    }
}

 

코드 리뷰

1. 물건의 가격 = num / 가지고 있는 돈 = pay / 거스름돈 = change

2. 거스름돈 = 가지고 있는 돈 - 물건의 가격

3. 각 동전마다 거스름돈으로 나눠주고 나머지를 구해주면 그것이 해당 동전의 개수

4. 모두 더해서 리턴

 

2번 문제 : 신지의 체크인 페이지

 

나는 이 문제를 해결하지 못했다.

문제를 너무 어렵게 생각했던 것 같은데, 저 새벽 5시와 24시간에 너무 집중을 해서 코드가 돌고 돌아갔던 것 같다.

그래서 정리를 할 겸 다시 풀어봤다.

 

새로 작성해본 코드

public class review {

    public static void main(String[] args) {
        review method = new review();
        int[] arr1 = {9, 7, 8, 9, 7, 9, 8};
        int[] arr2 = {23, 22, 26, 26, 29, 27, 22};
        System.out.println(method.solution(arr1, arr2));

    }

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

        return answer;
    }

}

 

코드 리뷰

1. answer 변수를 초기화(총 학습시간이 들어감)

2. 매주 월요일부터 일요일까지 (7일) 반복

3. 체크아웃 했던 시간이 29시(5시) 이전인지 확인해줌

4. 체크아웃 시간 - 체크인 시간 = 공부시간

5. 29시(5시) 이후면 21시(9시)로 바꿔주고 동일하게 공부시간을 구해줌

6. 총 공부시간 = answer을 리턴

 

3번 문제 : 소수 찾기

 

이 문제도 너무너무 어려웠다..ㅠㅠ

구글링의 도움을 많이 받아서 겨우겨우 풀었다.

 

작성 코드

public class test3 {
    public static void main(String[] args) {
        test3 method = new test3();
        String s = "15 3 10 9 7 8";
        System.out.println(method.solution(s));
    }

    public String solution(String s) {
        String[] numbers = s.split(" ");

        // max_value :  32비트로 표현가능한 최대 정수
        int a = Integer.MAX_VALUE;
        int b = Integer.MIN_VALUE;

        for (String str : numbers) {
            int num = Integer.parseInt(str);
            // 소수인지 확인하기
            boolean c = true;
            if (num <= 1) {
                c = false;
            } else {
                for (int i = 2; i <= Math.sqrt(num); i++) {
                    if (num % i == 0) {c = false; break;}
                }
            }
            if (c) {
                b = Math.max(b, num);
            } else {
                a = Math.min(a, num);
            }
        }
        return (a + " " + b);
    }
}

 

 

코드 리뷰

1. split을 사용해서 공백을 기준으로 나눠줌

2. MAX_VALUE, MIN_VALUE : 각각 32비트로 표현 가능한 최대 정수와 최소 정수를 구하기

- 데이터 타입 중 정수형(Byte, Short, Integer, Long)으로 선언하고 MAX_VALUE, MIN_VALUE를 붙여주면 실제 데이터 타입이 표현 할 수 있는 숫자 범위 중 가장 큰 값과 가장 작은 값이 할당됨

3. for문 :  numbers의 각 요소인 str을 반복 (str : 숫자를 포함한 문자열)

4. parseInt 메서드를 통해 str을 정수로 변환해줌

5. boolean c를 true로 초기화 : num이 소수인지 나타내기

6. num이 1이하라면 소수가 될 수 없음 -> c = false

7. 1보다 큰 경우 소수인지 확인하기 위해 else 입력

8. (구글링을 통해 해결해서 왜 제곱근이 사용되는지 잘 모르겠음)

9. c = true : num이 소수기 떄문에 최댓값 b가 들어감

10. c = false : num이 소수가 아니기 때문에 최솟값 a가 들어감

 

8번 챗gpt한테 리뷰 받은 결과

  • 배경 : 소수는 1과 자기 자신만으로 나누어지는 자연수 즉, 소수는 어떤 자연수로도 나누어 떨어지지 않음
  • 제곱근의 활용 : 소수 여부를 판별하는 가장 일반적인 방법 중 하나는 해당 숫자의 제곱근까지만 확인하는 것. 왜냐하면 제곱근 이후의 숫자는 이미 이전에 확인한 숫자의 반대쪽에 위치하므로, 불필요한 계산을 줄일 수 있음.
  • 루프의 범위 : for (int i = 2; i <= Math.sqrt(num); i++) { ... }: 이 루프는 2부터 num의 제곱근까지 반복됨. 예를 들어, 100의 제곱근은 10입니다. 따라서 100을 나누는 가장 큰 수는 10임. 이후의 숫자로 나누는 것은 의미가 없음.
  • 효율성 : 제곱근까지만 반복하여 나머지 수를 확인함으로써, 소수인지 판별하는 데 필요한 계산을 줄일 수 있음 이는 특히 큰 숫자에 대해 소수 여부를 판별할 때 효과적

따라서, 소수를 판별할 제곱근을 이용하여 반복 범위를 결정하는 것은 계산 효율성과 관련이 있습니다.

 

그냥 이렇게만 봐서는 제곱근의 활용 부분이 전혀 이해가 안되서, 다시 한 번 더 물어봤다.

  1. 소수:

소수는 1과 자신 외에 양의 약수가 없는 1보다 큰 자연수입니다. 즉, 1과 숫자 자체 이외의 다른 숫자로는 균등하게 나눌 수 없습니다.

 

1. 제곱근을 이용한 최적화:

- 숫자 'num'이 소수인지 확인할 때, 제곱근까지의 나눗셈만 확인하면 됩니다. 이는 'num'이 제곱근보다 큰 숫자로 나누어지면 이미 확인한 대로 해당하는 더 작은 인수로도 나누어질 수 있기 때문입니다.

- 예를 들어 num이 20으로 나누어지면 5로도 나누어져야 합니다(5 * 4 = 20이기 때문). 따라서 이미 'num'의 제곱근까지 가분성을 확인했다면 이미 5를 인수로 확인했을 것입니다.

 

2. 불필요한 계산 줄이기:

- 'num'의 제곱근에서 가분성 검사를 중지함으로써 더 큰 숫자에 대한 불필요한 계산을 피합니다. 이 최적화는 'num'의 크기가 커짐에 따라 점점 더 가치가 높아집니다.

- 큰 수의 경우 제곱근까지의 나눗셈을 확인하면 알고리즘에 필요한 반복 횟수가 크게 줄어들어 실행 속도가 빨라집니다.

 

3. 프라임 점검의 효율성:

- 소수 검사 알고리즘에서 제곱근을 활용하면 가장 관련성이 높은 잠재적 제수 범위에 계산을 집중하여 프로세스를 최적화합니다. 이는 특히 더 큰 수의 경우 소수 결정의 효율성을 향상시킵니다.

- 본질적으로, 가분성 검사를 숫자의 제곱근으로 제한함으로써 우리는 계산 효율성과 소수의 정확한 결정 사이의 균형을 유지합니다.

 

완벽하게 이해가 된 것은 아니지만 어느정도 감은 잡혔고 그냥 소수 여부를 판별할 때 사용하는 식인 것 같았다.