본문 바로가기
코딩테스트 연습

프로그래머스 상호 평가 Level 1

by 동배_ 2021. 8. 23.

문제 설명

https://programmers.co.kr/learn/courses/30/lessons/83201?language=java 

    • 대학 교수인 당신은, 상호평가를 통하여 학생들이 제출한 과제물에 학점을 부여하려고 합니다. 아래는 0번부터 4번까지 번호가 매겨진 5명의 학생들이 자신과 다른 학생의 과제를 평가한 점수표입니다.
      No. 0 1 2 3 4
      0 100 90 98 88 65
      1 50 45 99 85 77
      2 47 88 95 80 67
      3 61 57 100 80 65
      4 24 90 94 75 65
      평균 45.5 81.25 97.2 81.6 67.8
      학점 F B A B D
      위의 점수표에서, i행 j열의 값은 i번 학생이 평가한 j번 학생의 과제 점수입니다.
      • 0번 학생이 평가한 점수는 0번 행에담긴 [100, 90, 98, 88, 65]입니다.
        • 0번 학생은 자기 자신에게 100점, 1번 학생에게 90점, 2번 학생에게 98점, 3번 학생에게 88점, 4번 학생에게 65점을 부여했습니다.
      • 2번 학생이 평가한 점수는 2번 행에담긴 [47, 88, 95, 80, 67]입니다.
        • 2번 학생은 0번 학생에게 47점, 1번 학생에게 88점, 자기 자신에게 95점, 3번 학생에게 80점, 4번 학생에게 67점을 부여했습니다.
      당신은 각 학생들이 받은 점수의 평균을 구하여, 기준에 따라 학점을 부여하려고 합니다.
      만약, 학생들이 자기 자신을 평가한 점수가 유일한 최고점 또는 유일한 최저점이라면 그 점수는 제외하고 평균을 구합니다.
      • 0번 학생이 받은 점수는 0번 열에 담긴 [100, 50, 47, 61, 24]입니다. 자기 자신을 평가한 100점은 자신이 받은 점수 중에서 유일한 최고점이므로, 평균을 구할 때 제외합니다.
        • 0번 학생의 평균 점수는 (50+47+61+24) / 4 = 45.5입니다.
      • 4번 학생이 받은 점수는 4번 열에 담긴 [65, 77, 67, 65, 65]입니다. 자기 자신을 평가한 65점은 자신이 받은 점수 중에서 최저점이지만 같은 점수가 2개 더 있으므로, 유일한 최저점이 아닙니다. 따라서, 평균을 구할 때 제외하지 않습니다.
        • 4번 학생의 평균 점수는 (65+77+67+65+65) / 5 = 67.8입니다.
      제외할 점수는 제외하고 평균을 구한 후, 아래 기준에 따라 학점을 부여합니다.
      • 평균                                                                                                            학점
        90점 이상 A
        80점 이상 90점 미만 B
        70점 이상 80점 미만 C
        50점 이상 70점 미만 D
        50점 미만 F
        학생들의 점수가 담긴 정수형 2차원 배열 scores가 매개변수로 주어집니다. 이때, 학생들의 학점을 구하여 하나의 문자열로 만들어서 return 하도록 solution 함수를 완성해주세요.
        제한사항
      • 2 ≤ scores의 행의 길이(학생 수) ≤ 10
      • scores의 열의 길이 = scores의 행의 길이
        • 즉, scores는 행과 열의 길이가 같은 2차원 배열입니다.
      • 0 ≤ scores의 원소 ≤ 100
      • return 값 형식
        • 0번 학생의 학점부터 차례대로 이어 붙인 하나의 문자열을 return 합니다.

문제 해석 및 풀이 방법

1. 먼저 최소값과 최댓값을 찾는다.

2. 그 후 한배열씩 비교하며 자기자신을 평가하는 항목을 찾으면서 더해준다.

3. 자기자신의 위치를 찾으면 최솟값인지 최솟값인지, 그리고 중복된 값이 있는지 확인한다.

4. 중복된 값이 없으면 그 값을 빼고 평균을 구하고 아니면 함께 구한다.

 

내가 작성한 소스코드(Java)

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

class Solution {
    public String solution(int[][] scores) {
        StringBuilder answer = new StringBuilder();
        int size = scores.length;
        
        for(int i=0;i<size;i++){
            int min = 100;
            int max = 0;
            int sum = 0;
            int checkCount = 0;
            int checkCount2 = 0;
            int miner = 0;   
            int count =size;
            for(int j=0;j<size;j++){
                if(min > scores[j][i]) min = scores[j][i];
                if(max < scores[j][i]) max = scores[j][i];
            }
            for(int j=0;j<size;j++){
                if(min == scores[j][i]) checkCount++;
                if(max == scores[j][i]) checkCount2++;
            }
            
            for(int j=0;j<size;j++){
                if(j==i){
                    if(scores[j][i] == min && checkCount <= 1){
                        miner = scores[j][i];
                        count--;
                    }
                    else if(scores[j][i] == max && checkCount2 <= 1){
                        miner = scores[j][i];
                        count--;
                    }
                }
                sum += scores[j][i];
            }
            sum -= miner;
            answer.append(Grade((double)sum/(double)count));
        }  
            return answer.toString();
        }
    
    private char Grade(double grade) {
        if (grade >= 90.0) {
            return 'A';
        } else if (grade >= 80.0) {
            return 'B';
        } else if (grade >= 70.0) {
            return 'C';
        } else if (grade >= 50.0) {
            return 'D';
        } else {
            return 'F';
        }
    }
}

for문을 학생 수 만큼 만든 후 최솟값, 최댓값 , 합, 중복값 확인, 학생수(count) 변수를 선언한다.

그리고 for문을 안에 다시 생성해 최소값 최대값을 구한다.

그리고 for문을 통해 중복값을 찾는다. 

 

그런 후 for문을 또 생성해 i == j 자기가 자신을 평가한 항목을 본 후 그값이 최소인지 최대인지 중복인지를 확인한다 그리고 중복이 아니고 최소 또는 최대값이면 그 값을 miner에 대입한다. 그리고 count를 1뺀다. (평균을 구할 때 한명 뺴기위해서)

그리고 sum을통해 자신의 평가된 점수들을 더한다.

그리고 전체 더한 sum에서 miner를 빼고 평균값을 Grade 메소드의 매개변수로 주어 등급을 return 받는다.

 

그후 StringBuilder타입의 변수인 answer에 append를 통해 그 등급을 붙힌다. 

 

이것을 반복한후 마지막에 answer을 반환한다.

결론 및 고찰

처음에 문제를 딱보고 풀었지만 고생했다. 그 이유는 처음에 이중 폴문을 통해 score[i][j]형식으로 했었는데 알고보니 score[j][i] 형식으로 평가항목이 이루어져 있었고 이걸 인지하지 못해 조금 많이 돌아서 갔다. 그리고 마지막 Answer은 처음에 String 타입이였는데 어떻게 효율적으로 붙힐까 고민을 했었고 Level 1 목표시간인 30분이 지난 후 인터넷 검색을 통해 StringBuilder라는 타입을 알았다. 이건 파이썬에서 문자열 하는 방법이랑 유사해서 사용하기 편리했다.

 

소요 시간 50

댓글