문제
인하대학교 컴퓨터공학과를 졸업하기 위해서는, 전공평점이 3.
3 이상이거나 졸업고사를 통과해야 한다. 그런데 아뿔싸, 치훈이는 깜빡하고 졸업고사를 응시하지 않았다는 사실을 깨달았다!
치훈이의 전공평점을 계산해주는 프로그램을 작성해보자.
전공평점은 전공과목별 (학점 × 과목평점)의 합을 학점의 총합으로 나눈 값이다.
인하대학교 컴퓨터공학과의 등급에 따른 과목평점은 다음 표와 같다.
A+ | 4.5 |
A0 | 4.0 |
B+ | 3.5 |
B0 | 3.0 |
C+ | 2.5 |
C0 | 2.0 |
D+ | 1.5 |
D0 | 1.0 |
F | 0.0 |
P/F 과목의 경우 등급이 P또는 F로 표시되는데, 등급이 P인 과목은 계산에서 제외해야 한다.
과연 치훈이는 무사히 졸업할 수 있을까?
입력
20줄에 걸쳐 치훈이가 수강한 전공과목의 과목명, 학점, 등급이 공백으로 구분되어 주어진다.
출력
치훈이의 전공평점을 출력한다.
정답과의 절대오차 또는 상대오차가 10−4 이하이면 정답으로 인정한다.
제한
- 1 ≤ 과목명의 길이 ≤ 50
- 과목명은 알파벳 대소문자 또는 숫자로만 이루어져 있으며, 띄어쓰기 없이 주어진다. 입력으로 주어지는 모든 과목명은 서로 다르다.
- 학점은 1.0,2.0,3.0,4.0중 하나이다.
- 등급은 A+,A0,B+,B0,C+,C0,D+,D0,F,P중 하나이다.
- 적어도 한 과목은 등급이 P가 아님이 보장된다.
예제 입력 1
ObjectOrientedProgramming1 3.0 A+
IntroductiontoComputerEngineering 3.0 A+
ObjectOrientedProgramming2 3.0 A0
CreativeComputerEngineeringDesign 3.0 A+
AssemblyLanguage 3.0 A+
InternetProgramming 3.0 B0
ApplicationProgramminginJava 3.0 A0
SystemProgramming 3.0 B0
OperatingSystem 3.0 B0
WirelessCommunicationsandNetworking 3.0 C+
LogicCircuits 3.0 B0
DataStructure 4.0 A+
MicroprocessorApplication 3.0 B+
EmbeddedSoftware 3.0 C0
ComputerSecurity 3.0 D+
Database 3.0 C+
Algorithm 3.0 B0
CapstoneDesigninCSE 3.0 B+
CompilerDesign 3.0 D0
ProblemSolving 4.0 P
예제 출력 1
3.284483
예제 입력 2
BruteForce 3.0 F
Greedy 1.0 F
DivideandConquer 2.0 F
DynamicProgramming 3.0 F
DepthFirstSearch 4.0 F
BreadthFirstSearch 3.0 F
ShortestPath 4.0 F
DisjointSet 2.0 F
MinimumSpanningTree 2.0 F
TopologicalSorting 1.0 F
LeastCommonAncestor 2.0 F
SegmentTree 4.0 F
EulerTourTechnique 3.0 F
StronglyConnectedComponent 2.0 F
BipartiteMatching 2.0 F
MaximumFlowProblem 3.0 F
SuffixArray 1.0 F
HeavyLightDecomposition 4.0 F
CentroidDecomposition 3.0 F
SplayTree 1.0 F
예제 출력 2
0.000000
이 문제를 보고 가장먼저 떠올랐던 풀이 방법은 등급을 A,B,C,D와 뒤의부분이 +인지 아닌지를 판단하는 로직으로 등급을 평점으로 환산하고 P일때는 학점값을 0으로 하면 전공학점도0이되고, 학점도0이니까 최종결과값에는 똑같이 지장이 없을거라 생각해 ((학점*과목평점)값의 총점) / ( 학점들의 총점)를 각 줄마다 계산하여 더해준다음 마지막에 해당 연산을 해주면 끝일 거라 생각하였기에 아래와 같이 풀이를 진행해보았다.
주석 및 테스트 코드 포함
package BAEKJOON_25206;
/*
날짜: 2024.08.02.금
내용: 백준 25206번 문제 (너의 평점은 - 실5)
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class BAEKJOON_25206 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double sum = 0.00; // 학점의 총점을 저장할 변수
double majorSum = 0.00; // 전공학점의 총점을 저장할 변수
double majorRating = 0.00;
for(int i=0; i < 20; i++) {
String str = br.readLine(); // 20과목들을 for 반복문을 통해 순회하며 전공학점의 총점과 학점의 총점을 구하기
String[] arr = str.split(" ");
double grade = 0.00; // 등급에 따른 환산 학점 저장할 변수
if(arr[2].charAt(0) == 'A' ) { // 등급을 환솬점수로 환산, P면 해당 입력줄 스킵
grade = 4;
}else if(arr[2].charAt(0) == 'B') {
grade = 3;
}else if(arr[2].charAt(0) == 'C') {
grade = 2;
}else if(arr[2].charAt(0) == 'D') {
grade = 1;
}else if(arr[2].charAt(0) == 'F') {
grade = 0;
}else if(arr[2].charAt(0) == 'P') {
grade = 0;
}
if(arr[2].length() > 1 && arr[2].charAt(1) == '+') { // A+, B+, C+, D+는 0.5씩 학점추가
grade += 0.5;
}
majorSum += (Double.parseDouble(arr[1]) * grade); // 전공 학점의 총점 계산
sum += grade; // 학점의 총점 구하기
if (sum != 0) { // 전공평점의 총점 구하기 + 0으로 나누며 생기는 NAN관련 예외처리
majorRating = majorSum / sum;
} else {
majorRating = 0.00;
}
// System.out.println((i+1)+"번째 Sum: "+sum);
// System.out.println((i+1)+"번째 majorSum: "+(Double.parseDouble(arr[1]))+" * "+grade+" = "+majorSum);
// System.out.println((i+1)+"번째 majorRating: "+(majorSum)+"/"+sum+"="+majorRating);
}
System.out.println("전공평점: " + majorRating);
br.close();
}
}
백준 제출용
package BAEKJOON_25206;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double sum = 0.00;
double majorSum = 0.00;
double majorRating = 0.00;
for(int i=0; i < 20; i++) {
String str = br.readLine();
String[] arr = str.split(" ");
double grade = 0.00;
if(arr[2].charAt(0) == 'A' ) {
grade = 4;
}else if(arr[2].charAt(0) == 'B') {
grade = 3;
}else if(arr[2].charAt(0) == 'C') {
grade = 2;
}else if(arr[2].charAt(0) == 'D') {
grade = 1;
}else if(arr[2].charAt(0) == 'F') {
grade = 0;
}else if(arr[2].charAt(0) == 'P') {
grade = 0;
}
if(arr[2].length() > 1 && arr[2].charAt(1) == '+') {
grade += 0.5;
}
majorSum += (Double.parseDouble(arr[1]) * grade);
sum += grade;
if (sum != 0) {
majorRating = majorSum / sum;
} else {
majorRating = 0.00;
}
}
System.out.println(majorRating);
br.close();
}
}
풀이에는 문제가 없어 보였는데 결과값이 다르게 나와 머리를 싸메다 결국 다른 사람의 풀이를 참조해보게 되었는데, if ~ else if ~ else 문이 아니라 switch문을 활용하고 있었다. 하지만 로직은 같은거 같은데 왜 결과값이 다른건지 아직까지 잘 이해되지 않았는데 알고보니 등급학점에 따른 점수를 평상시쓰는 학점개념과 혼동하여 전공학점의 평균값을 등급에 따른 환삼점수들의 총합으로 나누어 구하고 있었다 ( 등급에 따른 환산 점수가 아니라 전공점수 3.0 로 입력되는 값들의 총합으로 나눠야줘야 함)
분명 로직에는 문제가 없었는데 왜 값이 다르게 나오는지 멘탈도 갈리고 시간도 1시간넘게 갈리고 있었는데 결국 변수명의 혼도이었다니,, 변수명을 뭐로 선언하는지가 정말 중요하다는 것을 몸으로 느끼는 시간이었다...
다른 사람 참고 코드
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
double result = 0, credit_sum = 0; // result = 학점*과목평균, credit_sum = 학점의 총합
char c;
for(int i=0;i<20;i++) {
double credit = 0; // 학점
double grade = 0; // 등급에 따른 점수
String str_arr[] = sc.nextLine().split(" ");
credit += Double.parseDouble(str_arr[1]);
c = str_arr[2].charAt(0);
switch(c) {
case 'A':
if(str_arr[2].charAt(1) == '+') grade += 4.5;
else grade += 4.0;
break;
case 'B':
if(str_arr[2].charAt(1) == '+') grade += 3.5;
else grade += 3.0;
break;
case 'C':
if(str_arr[2].charAt(1) == '+') grade += 2.5;
else grade += 2.0;
break;
case 'D':
if(str_arr[2].charAt(1) == '+') grade += 1.5;
else grade += 1.0;
break;
case 'F':
grade += 0;
break;
case 'P':
grade += 0;
credit = 0;
break;
}
credit_sum += credit;
result += credit*grade;
}
sc.close();
System.out.println(result/credit_sum);
}
}
참조하여 수정한 코드
package BAEKJOON_25206;
/*
날짜: 2024.08.02.금
내용: 백준 25206번 문제 (너의 평점은 - 실5)
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class BAEKJOON_25206 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double sum = 0; // 학점의 총점을 저장할 변수
double majorSum = 0; // 전공학점의 총점을 저장할 변수
double majorRating = 0;
for(int i=0; i < 20; i++) {
String str = br.readLine(); // 20과목들을 for 반복문을 통해 순회하며 전공학점의 총점과 학점의 총점을 구하기
String[] arr = str.split(" ");
double grade = 0; // 등급에 따른 환산 학점 저장할 변수
if(arr[2].charAt(0) == 'A' ) { // 등급을 환솬점수로 환산, P면 해당 입력줄 스킵
grade = 4;
}else if(arr[2].charAt(0) == 'B') {
grade = 3;
}else if(arr[2].charAt(0) == 'C') {
grade = 2;
}else if(arr[2].charAt(0) == 'D') {
grade = 1;
}else if(arr[2].charAt(0) == 'F') {
grade = 0;
}else if(arr[2].charAt(0) == 'P') {
grade = 0;
}
if(arr[2].length() > 1 && arr[2].charAt(1) == '+') { // A+, B+, C+, D+는 0.5씩 학점추가
grade += 0.5;
}
if (sum != 0) { // 전공평점의 총점 구하기 + 0으로 나누며 생기는 NAN관련 예외처리
majorRating = majorSum / sum;
} else {
majorRating = 0;
}
majorSum += (Double.parseDouble(arr[1]) * grade); // 전공 학점의 총점 계산
sum += (Double.parseDouble(arr[1])); // 전공 학점의 총점 구하기
// System.out.println((i+1)+"번째 Sum: "+sum);
// System.out.println((i+1)+"번째 majorSum: "+(Double.parseDouble(arr[1]))+" * "+grade+" = "+majorSum);
// System.out.println((i+1)+"번째 majorRating: "+(majorSum)+"/"+sum+"="+majorRating);
}
System.out.println("전공평점: " + majorRating);
br.close();
}
}
'실습 > 백준' 카테고리의 다른 글
그룹 단어 체커 - 1316번 (Java 풀이) (0) | 2024.07.21 |
---|---|
크로아티아 알파벳 - 2941번 (Java 풀이) (2) | 2024.07.20 |
단어 공부 - 1157번 (Java 풀이) (0) | 2024.07.19 |
팰린드롬인지 확인하기 - 10988번 (Java 풀이) (0) | 2024.07.18 |
별 찍기 7 - 2444번 (Java 풀이) (0) | 2024.07.18 |