: solved.ac - Bronze 1

 

https://www.acmicpc.net/problem/2755

 

2755번: 이번학기 평점은 몇점?

첫째 줄에, 백준이가 이번 학기에 들은 과목 수가 주어진다. 둘째 줄부터 N개의 줄에 각 과목의 과목명, 학점, 성적이 주어진다. 과목명은 알파벳 소문자와 숫자, 그리고 밑줄 (_)로만 이루어져 있

www.acmicpc.net

 

 

 

예제 입력

7
General_Physics_1 3 A+
Introduction_to_Computer_Science_and_Eng 3 B0
Reading_And_Writing 2 C0
English_1 3 C+
Analytic_Geometry_and_Calculus_1 3 B+
Fortran_Programming 3 B+
C_Language_Programming 3 A+

 

예제 출력

3.28

 

 

정답

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

double grader(char* grade) {
	float g = 0;
	if (grade[0] == 'A') g = 4;
	else if (grade[0] == 'B') g = 3;
	else if (grade[0] == 'C') g = 2;
	else if (grade[0] == 'D') g = 1;
	else {
		g = 0;
		return g;
	}

	if (grade[1] == '+') g += 0.3;
	else if (grade[1] == '-') g -= 0.3;
	return g;
}

int main() {
	char string[110] = {'\0'};
	int num, score=0;
	double grade = 0; 
	
	scanf("%d", &num);

	for (int i = 0; i < num; i++) {
		scanf("%s", string);

		scanf("%s", string);
		int scr = string[0] - 48;
		score += scr;

		scanf("%s", string);
		double grd = grader(string);
		grade += (grd * scr);
	}

	float result = grade /= score;
	printf("%.2f", result);

	return 0;
}


해설

 

: 연속적으로 주어지는 자료를 잘 분할해서 처리할 수 있으면 쉽게 풀 수 있다.

 

 

1. 필요한 변수들을 선언하고 입력을 받는다.

이번 문제에서 스트링을 입력받을 때는 반드시 scanf 함수에서 %s 문자를 써서 입력받아야 한다.

이 문제는 공백을 기준으로 과목명/학점/성적을 분리해 입력할 필요가 있는데,

gets는 개행 문자를 기준으로 문자열을 끊기 때문에 strtok 등의 함수로 따로 문자열을 또 끊어주어야 한다.

(심지어 그렇게 해도 잘 작동되지 않는다.)

반면 scanf는 공백 문자를 기준으로 알아서 문자열을 끊어주므로 이번 문제에 더 적합하다.

과목명은 결과와 관련이 없으므로 입력을 받고 별다른 처리를 하지 않아도 된다.

int main() {
	char string[110] = {'\0'}; //문자열을 입력받을 버퍼
	int num, score=0;
	double grade = 0; 
	// 과목수, 학점, 성적
	
	scanf("%d", &num);

	for (int i = 0; i < num; i++) {
		scanf("%s", string);
		//과목명 입력

 

2. 학점 부분이다. 평점을 구하는 식이 (학점*성적) / 학점 총합 임에 유의하라.

개별 학점과 학점 총합이 따로 다루어져야 하므로 변수 scr을 for문 안에 만들어서 문자를 정수로 바꾼 값을 넣어주었다.

이 값은 for문이 돌 때마다 과목별로 갱신될 것이고, 과목 학점 합산은 for문 밖에 만들어진 변수이므로 합산만 될 것이다.

		scanf("%s", string);
		//학점 입력
		int scr = string[0] - 48;
		//0의 아스키코드값을 빼서 문자로부터 정수 추출
		score += scr;
		//전체 학점에 해당 과목 학점 합산

 

3. 성적을 나타내는 문자열을 함수에 넣어 성적 실수값을 산출한다. (함수 본체는 아래 참고)

전체 성적을 담을 실수형 변수에 (학점*성적) 값을 합산해준다.

여기까지의 과정을 과목의 수만큼 반복한다.

		scanf("%s", string);
		double grd = grader(string);
		//함수로 문자에서 성적 실수값 추출
		grade += (grd * scr);
		//전체 성적에 해당 과목 성적*학점 합산
	}
double grader(char* grade) {
	float g = 0;
	if (grade[0] == 'A') g = 4;
	else if (grade[0] == 'B') g = 3;
	else if (grade[0] == 'C') g = 2;
	else if (grade[0] == 'D') g = 1;
	else {
		g = 0;
		return g;
	}

	if (grade[1] == '+') g += 0.3;
	else if (grade[1] == '-') g -= 0.3;
	return g;
}

 

4. (학점*성적) 합계를 학점 총합으로 나누어 평점을 구한다.

문제 조건에서는 실수인 평점을 반올림하여 소수점 두 자리까지 나타내도록 되어 있는데,

형식 문자인 %.nf(또는 %.nlf)를 사용하면 알아서 반올림하여 소수점 두 자리까지 나타내 준다.

다만 하나 유의해야 할 것은 이때 평점을 담은 변수가 float형이거나 그 형으로 명시적 형변환되어야 한다는 것이다.

정밀도 문제로 double형은 반올림을 해도 제대로 되지 않는 경우가 종종 있다. (더 정밀한 것이 언제나 좋은 것은 아니다.)

	float result = grade /= score;
	//성적 합계를 학점 합계로 나눔
	printf("%.2f", result);

 

'C언어 > BAEKJOON' 카테고리의 다른 글

[백준] 1110. 더하기 사이클  (0) 2022.07.13
[백준] 1157. 단어 공부  (0) 2022.07.13
[백준] 1834. 나머지와 몫이 같은 수  (0) 2022.07.06
[백준] 2164. 카드2  (0) 2022.06.25
[백준] 1929. 소수 구하기  (0) 2022.06.25

+ Recent posts