: 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 |