<2.7> 점수 계산

mutexlocking·2022년 7월 18일
0

문제
: 각 문제에 대해 (1: 맞음 , 0: 틀림) 맞은 여부가 주어지면, 이를 가지로 점수를 계산하시오.
만약 주어진 값이 1이면 문제를 맞혔단 의미이므로 1점이 누적되고, 주어진 값이 0이면 문제를 틀렸단 의미이므로 점수가 누적되지 않는다.
또한 주어진 값이 1 1 1 로써 3문제를 연속으로 맞힌 경우,
가산점을 부여하여 첫 번째 문제는 1점, 2번째 문제는 2점, 3번째 문제는 3점을 누적시킨다.
이와같이 k개의 문제를 연속으로 맞힌 경우 , k점을 누적시키는 가산점을 고려하여 총 점수를 계산하라.

이 문제의 요구사항은 결국 "정답 여부를 순서대로 탐색하면서 , 연속된 1을 감지하여 그에 따른 가산점을 부과하는것" 이라고 할 수 있다.

  1. 이에 대한 해결 로직으로써 나는 처음에 스택을 사용하려고 했었다. 0을 분기점으로 사용하여 , 1을 계속 스택에 쌓아간다면 , 연속된 1에 대한 가산점을 쉽게 계산할 수 있을 것이라 생각하였기 때문이다.
  1. 그런데 가산점이 매겨지는 방식을 잘 보니, 연속된 1의 개수가 3이면 1+2+3점을 누적하는 방식이었고, 연속된 1의 개수가 5이면 1+2+3+4+5점을 누적하는 방식이었다.
    즉 "연속된 1의 개수만큼 ,1부터 k까지의 자연수의 합" 이라는 규칙을 발견하였다.
  • 따라서 스택을 사용하지 않고, 단순히 연속된 1을 count하는 것 만으로, 위의 규칙을 통해 가산점을 쉽게 계산할 수 있었다.
  • 또한 나의 경우는 0을 만났을 때 , 연속된 1의 개수에 대한 가산점을 계산하여 총 점수에 누적시키는 방식을 사용하였는데,
    • 이때 마지막 정답 여부가 1이면 , 더이상 0을 만나지 않아서 마지막 부분 점수가 누적되지 않는 문제가 있었다.
    • 따라서 순차탐색 이후, 연속된 1의 개수가 0인의 여부를 한번 더 확인하여 부분 점수를 누적시키는 작업이 필요하였다.
      (실제로 이 작업을 빠뜨려서 문제를 틀렸다.)

위 해결 로직에 따른 실제 구현 코드는 아래와 같다.

import java.util.Scanner;


public class Main {

    public static int solution(int[] arr, int N){
        int cnt = 0;
        int sum = 0;

        for(int i=0; i<N; i++){
            
            // 연속된 1의 개수를 count하고
            if(arr[i] == 1) cnt++;

            //0을 만나면 , 연속된 1의 개수만큼의 부분 점수를 계산하여 총 점수에 누적
            else{
                sum += getSubTotal(cnt);
                cnt = 0;
            }
        }
    
        //단 마지막 부분 점수가 누적되지 않을 수 있으니, 이를 확인하여 누적시켜줘야 함.
        if(cnt > 0)
            sum += getSubTotal(cnt);

        return sum;
    }

    public static int getSubTotal(int n){
        int sum = 0;
        for(int i=1; i<=n; i++) {
            sum += i;
        }

        return sum;
    }
    

    public static void main(String[] args) {
        //0. Scanner 준비
        Scanner sc = new Scanner(System.in);

        //1. N과 각 점수 입력
        int N = sc.nextInt();

        int[] arr = new int[N];
        for(int i=0; i<N; i++){
            arr[i] = sc.nextInt();
        }


        //2. N과, 점수가 담긴 arr을 인자로 넘기면서 solution()을 호출하여 , 결과를 반환받음
        int result = solution(arr, N);

        //3. 반환받은 결화를 출력
        System.out.println(result);
    }


}

[느낀점]
이번 문제를 고민하면서,
단순히 문제의 유형을 파악하고 - 이를 어떤 자료구조 또는 알고리즘을 사용하여 해결해야 겠다 , 라고만 생각하던 기존의 습관을 버리고

문제 그 자체만으로 어떤것을 발견할 수 있는지를 좀더 깊게 고민해봐야 겠다고 느꼈다.

배달의 민족 CEO 김범준 님의 말씀처럼 ,
개발자는 단순히 코딩하는 사람이 아니라, 어떻게 하면 문제를 더 쉽게 해결할 수 있을 지 고민하는 사람 이기 때문이다.

[선생님 풀이]

  • 하하 ,,, 그런데 단순히 연속된 1의 개수인 cnt를 누적시키는것 만으로도 충분히 가산점을 고려하여 최종 점수를 계산할 수 있었다..
  • 차라리 이게 더 쉽고 효율적인 방법이었다..!!
profile
개발자가 되고자 try 하는중

0개의 댓글