백준 1546 - 평균
세준이는 기말고사를 망쳤다. 세준이는 점수를 조작해서 집에 가져가기로 했다. 일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다.
예를 들어, 세준이의 최고점이 70이고, 수학점수가 50이었으면 수학점수는 50/70*100이 되어 71.43점이 된다.
세준이의 성적을 위의 방법대로 새로 계산했을 때, 새로운 평균을 구하는 프로그램을 작성하시오.
첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보다 크다.
첫째 줄에 새로운 평균을 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가 10^²이하이면 정답이다.
무슨 시험 과목이 1000보다 작거나 같냐. 세준이는 엘리트 학교에 다니나보다.
상대오차를 허용한다고는 했지만 float보다는 정확한 double을 이용했다.
#include <stdio.h>
#include <stdlib.h>
int main(void){
double *a, sum = 0;
int i, n, m;
scanf("%d", &n);
a = (double*)malloc(sizeof(double)*n);
for(i=0; i<n; i++){
scanf("%lf", &a[i]);
}
m = a[0];
for(i=1; i<n; i++){
if(m < a[i]) m = a[i];
}
for(i=0; i<n; i++){
a[i] = a[i]/m*100;
sum += a[i];
}
printf("%lf", sum/n);
return 0;
}
n이 1000이하인데 굳이 메모리할당을 쓸 필요 있나 싶지만 과거의 나는 썼다. 효율에 미쳐있던 시기...
점수를 받아서 max값 m을 찾아주고, 모든 점수를 점수/m*100으로 계산해줬다. a[i]가 갱신되었기 때문에 sum에서 다시 더해준 뒤 n으로 나눠서 평균을 찾았다.
백준 8958 - OX퀴즈
"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.
"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.
OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.
길이가 0보다 크고 80보다 작은 문자열
이 문제 풀면서 꽤 고생했던 기억이 있다. 연속된 O일 때 점수를 구하고 X가 나올 때 변수를 초기화하면 쉽게 구할 수 있다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int n = 0, score, flag;
scanf("%d", &n);
for (int i = 0; i < n; i++) { //testcase n
char ox[81] = { 0 }; //초기화
scanf("%s", &ox);
int len = strlen(ox);
flag = 0, score = 0;
for (int j = 0; j < len; j++) {
if (ox[j] == 'O') {
flag++;
score += flag;
}
else {
flag = 0;
}
}
printf("%d\n", score);
}
return 0;
}
flag를 사용해 O가 나올 때마다 +1한다. score에는 누적 점수를 더하고, X가 나오면 0으로 초기화한다.
백준 4344 - 평균은 넘겠지
대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.
첫째 줄에는 테스트 케이스의 개수 C가 주어진다.
둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.
문제 낸 사람이 상당히 악질이다. 원래 팩트가 더 아픈 법...
평균을 구해서 넘은 사람의 비율을 반올림하고 소수점 셋째 자리까지 출력하는 것을 유의한다.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int n, i, j, tc;
double sum = 0, *p;
int *ave;
scanf("%d", &tc);
p = (double*)malloc(sizeof(double)*tc); //ave 저장할 배열
for(i=0; i<tc; i++){
scanf("%d", &n);
ave = (int*)malloc(sizeof(int)*n); //n만큼 입력받은 거 저장
for(j=0; j<n; j++) scanf("%d", &ave[j]);
//for(j=0; j<n; j++) printf("%d ", ave[j]);
sum = 0;
for(j=0; j<n; j++){
sum = sum + ave[j];
//printf("%lf %d\n", sum, ave[j]);
}
sum /= n;
//printf("sum = %lf\n", sum);
p[i] = 0;
for(j=0; j<n; j++){
if((double)ave[j] > sum) p[i]++;
}
p[i] = p[i]/(double)n*100;
}
for(i=0; i<tc; i++) printf("%.3lf%%\n", p[i]);
return 0;
}
이 때는 테스트 케이스를 한번에 출력하기 위해 메모리 할당을 했는데 케이스 하나씩 출력해도 정답으로 인정된다.
변수도 많이 쓰고 상당히 복잡한 코드라 p를 쓰지 않고 다시 풀어봤다.
테스트 케이스 하나씩 출력
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int C;
scanf("%d", &C);
for (int tc = 0; tc < C; tc++) {
int n = 0;
double ave = 0, cnt = 0;
int* score;
scanf("%d", &n);
score = (int*)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
scanf("%d", &score[i]);
}
for (int i = 0; i < n; i++) {
ave += score[i];
}
ave /= n;
for (int i = 0; i < n; i++) {
if ((double)score[i] > ave)
cnt++;
}
printf("%.3lf%%\n", cnt / n * 100);
}
return 0;
}
코드를 많이 줄였다. ave는 평균, cnt는 평균을 넘은 학생 수이다. 점수를 입력받고 평균을 구한 뒤 평균을 넘은 학생을 cnt에 구했다. 비율이기 때문에 cnt를 n으로 나눈 뒤에 100을 곱해야 한다. 테스트 케이스 돌리면서 변수를 초기화하지 않으면 값이 덮어씌워지기 때문에 애초에 for문 초반에 변수를 새로 선언해버렸다.
'BOJ(백준)' 카테고리의 다른 글
[C언어] 백준 - 2920 음계 (0) | 2022.02.23 |
---|---|
[C언어] 백준 18108 - 1998년생인 내가 태국에서는 2541년생?! (0) | 2022.01.26 |
[C언어] 백준 2292 - 벌집 (0) | 2022.01.24 |
[C언어] 백준 - 2558, 7287, 2475, 10926 (0) | 2021.12.29 |
[C언어] 백준 2908 - 상수 (0) | 2021.02.27 |