문제 설명
https://programmers.co.kr/learn/courses/30/lessons/83201?language=java
-
- 대학 교수인 당신은, 상호평가를 통하여 학생들이 제출한 과제물에 학점을 부여하려고 합니다. 아래는 0번부터 4번까지 번호가 매겨진 5명의 학생들이 자신과 다른 학생의 과제를 평가한 점수표입니다.
No. 0 1 2 3 4 0 10090 98 88 65 1 50 4599 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 - 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의 행의 길이(학생 수) ≤ 10
- scores의 열의 길이 = scores의 행의 길이
- 즉, scores는 행과 열의 길이가 같은 2차원 배열입니다.
- 0 ≤ scores의 원소 ≤ 100
- return 값 형식
- 0번 학생의 학점부터 차례대로 이어 붙인 하나의 문자열을 return 합니다.
- 0번 학생이 평가한 점수는 0번 행에담긴 [100, 90, 98, 88, 65]입니다.
- 대학 교수인 당신은, 상호평가를 통하여 학생들이 제출한 과제물에 학점을 부여하려고 합니다. 아래는 0번부터 4번까지 번호가 매겨진 5명의 학생들이 자신과 다른 학생의 과제를 평가한 점수표입니다.
문제 해석 및 풀이 방법
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분
'코딩테스트 연습' 카테고리의 다른 글
Programmers 게임 맵 최단거리 Level 2 (0) | 2021.08.25 |
---|---|
프로그래머스 2016년 Level 1 (0) | 2021.08.24 |
프로그래머스 약수의 개수와 덧셈 Level 1 (0) | 2021.08.21 |
프로그래머스 폰켓몬 Level 1 (0) | 2021.08.20 |
프로그래머스 같은 숫자는 싫어 Level 1 (0) | 2021.08.19 |
댓글