실습/백준

너의 평점은 - 25206번 (Java 풀이)

chobyeonggyu03 2024. 8. 2. 15:36
반응형

문제

 

인하대학교 컴퓨터공학과를 졸업하기 위해서는, 전공평점이 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();
	}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형