문제
"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.
"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.
OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 0보다 크고 80보다 작은 문자열이 주어진다. 문자열은 O와 X만으로 이루어져 있다.
출력
각 테스트 케이스마다 점수를 출력한다.
예제 입력 1
5
OOXXOXXOOO
OOXXOOXXOO
OXOXOXOXOXOXOX
OOOOOOOOOO
OOOOXOOOOXOOOOX
예제 출력 2
10
9
7
55
30
예상 풀이방법
문자 배열 선언 후 해당 배열마다 O인지 X인지 판독하는 for문을 기점으로 if 조건문을 달아 O일 경우와 X일 경우를 구별해가며 풀어낸다.
1차 코드
#include <stdio.h>
#include <string.h>
int main() {
// 테스트 케이스의 갯수를 n이라고 가정하여 입력받기
int n;
scanf("%d", &n);
// 테스트 케이스의 갯수만큼의 반복문을 사용하여 OX를 문자열로 입력받기
for (int i = 0; i < n; i++) {
// 0보다 크고 80보다 작은 문자열 생성
char arr[80];
scanf("%s", arr);
// 입력받은 문자열의 길이 strlen(a)만큼을 반복문으로 사용하고 if문을 사용하여 각 배열에 저장된 O or X를 판독하기
for (int j = 0; j < strlen(arr); j++) {
int score = 0;
// 가장 먼저 선언되어야 할 X일 경우 아무것도 하지 않고 넘어간다.
if (arr[j] == 'X') {
continue;
}
// 두 번째로 선언되어야 할 if문은 'O'일 경우 점수를 증가시킬 수 있어야 한다.
else if (arr[j] == 'O') {
// if문 내에서 score를 선언할 경우 매 if문마다 초기화되므로 상위 개념인 for문에 int score를 선언하고 score++로 1 증가시킨다.
score++;
// j를 기준으로 이전 문자열이 O일 경우 1씩 추가 점수를 부여해야하기에 for문을 사용하여 이전 문자열을 찾아내지만 X를 발견하면 중단하는 반복문을 작성한다.
// j - 1이 0일 경우까지 전부 찾아내야하므로 int k를 j - 1로 지칭하여 점점 감소하는 반복문을 작성한다.
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
// 가장 먼저 들어가야하는 경우는 X를 찾아낼 경우 for문을 그만 돌리고 나오는 것이다.
if (arr[k] == 'X') {
break;
}
// 그 다음으로는 O일 경우 추가 점수를 주어야하는데 이 추가 점수가 몇 점일지 모르기 때문에 int sum이라는 함수를 추가하여 거기에 더해놓고
// for문이 끝날 때 score에 합산하는 방식을 사용한다. 그러면 만약 OOOO(마지막 O가 j라면)
/*
1 1 1
1 1
1
+ 맨 처음 j가 도는 함수에서 score++로 1점이 더해지기 때문에
4 + 3 + 2 + 1점이 완성되는 방식으로 계산할 수 있게 된다.
*/
else if (arr[k] == 'O') {
// int sum은 if마다 초기화되는게 아니라 해당 for문 내에서는 값이 유지되어야하기에 for문 바로 아래에 선언한다.
// 그리고 O일 경우마다 sum에 ++로 더해주고 그 값을 for문이 끝날 때, score에 합산한다.
sum++;
}
score += sum;
}
}
// 마지막으로 O or X가 아닐 경우 전부 예외처리를 하고 즉시 프로그램을 종료시킬 수 있도록 변수를 차단한다.
else
return 0;
// 모든 연산이 끝난 후 score값을 프린트한다.
printf("%d\n", score);
}
}
}
1차 결과
5
OOXXOXXOOO
1
2
1
1
2
3
OOXXOOXXOO
1
2
1
2
1
2
OXOXOXOXOXOXOX
1
1
1
1
1
1
1
OOOOOOOOOO
1
2
3
4
5
6
7
8
9
10
OOOOXOOOOXOOOOX
1
2
3
4
1
2
3
4
1
2
3
4
1차 진단
OX에 대한 점수는 잘 계산되었으나 각 O의 점수가 따로따로 출력되는 문제가 있다.
여기서 두 가지의 문제점을 짐작할 수 있었다.
- sum을 사용하여 점수를 합산하는 과정에서 문제가 있을 가능성
- printf("%d", score); 명령어가 잘못된 부분에 들어가있어서 반복적으로 출력했을 가능성
1차 해결 노력
우선 반복출력을 없애야 합산의 문제점도 추려내기 쉬워질 것 같았다.
그래서 1번이 아니라 2번 문제점부터 해결해보기로 했다.
- printf 명령어의 위치를 옮기기
printf 명령어를 for문 밖으로 옮겨보니 score가 정의된 위치 밖이었다.
그렇기에 해당 int score = 0;을 int j 반복문이 아닌 int i 반복문에 지정해놓았다.
어차피 매 테스트 케이스마다 초기화되는 곳이니 상관없었다.
2차 코드
#include <stdio.h>
#include <string.h>
int main() {
// 테스트 케이스의 갯수를 n이라고 가정하여 입력받기
int n;
scanf("%d", &n);
// 테스트 케이스의 갯수만큼의 반복문을 사용하여 OX를 문자열로 입력받기
for (int i = 0; i < n; i++) {
int score = 0;
// 0보다 크고 80보다 작은 문자열 생성
char arr[80];
scanf("%s", arr);
// 입력받은 문자열의 길이 strlen(a)만큼을 반복문으로 사용하고 if문을 사용하여 각 배열에 저장된 O or X를 판독하기
for (int j = 0; j < strlen(arr); j++) {
// 가장 먼저 선언되어야 할 X일 경우 아무것도 하지 않고 넘어간다.
if (arr[j] == 'X') {
continue;
}
// 두 번째로 선언되어야 할 if문은 'O'일 경우 점수를 증가시킬 수 있어야 한다.
else if (arr[j] == 'O') {
// if문 내에서 score를 선언할 경우 매 if문마다 초기화되므로 상위 개념인 for문에 int score를 선언하고 score++로 1 증가시킨다.
score++;
// j를 기준으로 이전 문자열이 O일 경우 1씩 추가 점수를 부여해야하기에 for문을 사용하여 이전 문자열을 찾아내지만 X를 발견하면 중단하는 반복문을 작성한다.
// j - 1이 0일 경우까지 전부 찾아내야하므로 int k를 j - 1로 지칭하여 점점 감소하는 반복문을 작성한다.
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
// 가장 먼저 들어가야하는 경우는 X를 찾아낼 경우 for문을 그만 돌리고 나오는 것이다.
if (arr[k] == 'X') {
break;
}
// 그 다음으로는 O일 경우 추가 점수를 주어야하는데 이 추가 점수가 몇 점일지 모르기 때문에 int sum이라는 함수를 추가하여 거기에 더해놓고
// for문이 끝날 때 score에 합산하는 방식을 사용한다. 그러면 만약 OOOO(마지막 O가 j라면)
/*
1 1 1
1 1
1
+ 맨 처음 j가 도는 함수에서 score++로 1점이 더해지기 때문에
4 + 3 + 2 + 1점이 완성되는 방식으로 계산할 수 있게 된다.
*/
else if (arr[k] == 'O') {
// int sum은 if마다 초기화되는게 아니라 해당 for문 내에서는 값이 유지되어야하기에 for문 바로 아래에 선언한다.
// 그리고 O일 경우마다 sum에 ++로 더해주고 그 값을 for문이 끝날 때, score에 합산한다.
sum++;
}
score += sum; // 주의
}
}
// 마지막으로 O or X가 아닐 경우 전부 예외처리를 하고 즉시 프로그램을 종료시킬 수 있도록 변수를 차단한다.
else
return 0;
}
// 모든 연산이 끝난 후 score값을 프린트한다.
printf("%d\n", score);
}
}
2차 결과
5
OOXXOXXOOO
10
OOXXOOXXOO
9
OXOXOXOXOXOXOX
7
OOOOOOOOOO
55
OOOOXOOOOXOOOOX
30
미흡했던 점
- int score = 0;의 선언과 pritnf("%d", score); 명령어를 테스트 케이스의 갯수마다 반복해야하는데 (int i 반복문마다 해야하는데)
문자열의 길이만큼 반복되는 반복문(int j 반복문)에 넣어놓으니 당연히 X일 경우 실행중지하고 O일 경우 해당 점수를 계산하여
반복적으로 출력했던 것이다.
개선 방안
- 각 반복문 및 모든 명령어, 함수 사용에 있어서 어느 부분에서 정의되어야하는지 위치를 정확히 알고 사용한다.
최종 코드
#include <stdio.h>
#include <string.h>
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int score = 0;
char arr[80];
scanf("%s", arr);
for (int j = 0; j < strlen(arr); j++) {
if (arr[j] == 'X') {
continue;
}
else if (arr[j] == 'O') {
score++;
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
if (arr[k] == 'X') {
break;
}
else if (arr[k] == 'O') {
sum++;
}
score += sum;
}
}
else
return 0;
}
printf("%d\n", score);
}
}
백준 실행 결과

'C > BaekJoon' 카테고리의 다른 글
[C] 백준 1977 - 완전제곱수 | BaekJoon (0) | 2023.08.01 |
---|---|
[C] 백준 2920 - 음계 | BaekJoon (0) | 2023.07.28 |
[C] 백준 2750 - 수 정렬하기 (순차 정렬) | BackJoon (0) | 2023.07.22 |
[C] 백준 2750 - 수 정렬하기 (선택 정렬) | BackJoon (0) | 2023.07.22 |
[C] 백준 2750 - 수 정렬하기 (삽입 정렬) | BackJoon (0) | 2023.07.21 |
문제
"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.
"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.
OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 0보다 크고 80보다 작은 문자열이 주어진다. 문자열은 O와 X만으로 이루어져 있다.
출력
각 테스트 케이스마다 점수를 출력한다.
예제 입력 1
5
OOXXOXXOOO
OOXXOOXXOO
OXOXOXOXOXOXOX
OOOOOOOOOO
OOOOXOOOOXOOOOX
예제 출력 2
10
9
7
55
30
예상 풀이방법
문자 배열 선언 후 해당 배열마다 O인지 X인지 판독하는 for문을 기점으로 if 조건문을 달아 O일 경우와 X일 경우를 구별해가며 풀어낸다.
1차 코드
#include <stdio.h>
#include <string.h>
int main() {
// 테스트 케이스의 갯수를 n이라고 가정하여 입력받기
int n;
scanf("%d", &n);
// 테스트 케이스의 갯수만큼의 반복문을 사용하여 OX를 문자열로 입력받기
for (int i = 0; i < n; i++) {
// 0보다 크고 80보다 작은 문자열 생성
char arr[80];
scanf("%s", arr);
// 입력받은 문자열의 길이 strlen(a)만큼을 반복문으로 사용하고 if문을 사용하여 각 배열에 저장된 O or X를 판독하기
for (int j = 0; j < strlen(arr); j++) {
int score = 0;
// 가장 먼저 선언되어야 할 X일 경우 아무것도 하지 않고 넘어간다.
if (arr[j] == 'X') {
continue;
}
// 두 번째로 선언되어야 할 if문은 'O'일 경우 점수를 증가시킬 수 있어야 한다.
else if (arr[j] == 'O') {
// if문 내에서 score를 선언할 경우 매 if문마다 초기화되므로 상위 개념인 for문에 int score를 선언하고 score++로 1 증가시킨다.
score++;
// j를 기준으로 이전 문자열이 O일 경우 1씩 추가 점수를 부여해야하기에 for문을 사용하여 이전 문자열을 찾아내지만 X를 발견하면 중단하는 반복문을 작성한다.
// j - 1이 0일 경우까지 전부 찾아내야하므로 int k를 j - 1로 지칭하여 점점 감소하는 반복문을 작성한다.
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
// 가장 먼저 들어가야하는 경우는 X를 찾아낼 경우 for문을 그만 돌리고 나오는 것이다.
if (arr[k] == 'X') {
break;
}
// 그 다음으로는 O일 경우 추가 점수를 주어야하는데 이 추가 점수가 몇 점일지 모르기 때문에 int sum이라는 함수를 추가하여 거기에 더해놓고
// for문이 끝날 때 score에 합산하는 방식을 사용한다. 그러면 만약 OOOO(마지막 O가 j라면)
/*
1 1 1
1 1
1
+ 맨 처음 j가 도는 함수에서 score++로 1점이 더해지기 때문에
4 + 3 + 2 + 1점이 완성되는 방식으로 계산할 수 있게 된다.
*/
else if (arr[k] == 'O') {
// int sum은 if마다 초기화되는게 아니라 해당 for문 내에서는 값이 유지되어야하기에 for문 바로 아래에 선언한다.
// 그리고 O일 경우마다 sum에 ++로 더해주고 그 값을 for문이 끝날 때, score에 합산한다.
sum++;
}
score += sum;
}
}
// 마지막으로 O or X가 아닐 경우 전부 예외처리를 하고 즉시 프로그램을 종료시킬 수 있도록 변수를 차단한다.
else
return 0;
// 모든 연산이 끝난 후 score값을 프린트한다.
printf("%d\n", score);
}
}
}
1차 결과
5
OOXXOXXOOO
1
2
1
1
2
3
OOXXOOXXOO
1
2
1
2
1
2
OXOXOXOXOXOXOX
1
1
1
1
1
1
1
OOOOOOOOOO
1
2
3
4
5
6
7
8
9
10
OOOOXOOOOXOOOOX
1
2
3
4
1
2
3
4
1
2
3
4
1차 진단
OX에 대한 점수는 잘 계산되었으나 각 O의 점수가 따로따로 출력되는 문제가 있다.
여기서 두 가지의 문제점을 짐작할 수 있었다.
- sum을 사용하여 점수를 합산하는 과정에서 문제가 있을 가능성
- printf("%d", score); 명령어가 잘못된 부분에 들어가있어서 반복적으로 출력했을 가능성
1차 해결 노력
우선 반복출력을 없애야 합산의 문제점도 추려내기 쉬워질 것 같았다.
그래서 1번이 아니라 2번 문제점부터 해결해보기로 했다.
- printf 명령어의 위치를 옮기기
printf 명령어를 for문 밖으로 옮겨보니 score가 정의된 위치 밖이었다.
그렇기에 해당 int score = 0;을 int j 반복문이 아닌 int i 반복문에 지정해놓았다.
어차피 매 테스트 케이스마다 초기화되는 곳이니 상관없었다.
2차 코드
#include <stdio.h>
#include <string.h>
int main() {
// 테스트 케이스의 갯수를 n이라고 가정하여 입력받기
int n;
scanf("%d", &n);
// 테스트 케이스의 갯수만큼의 반복문을 사용하여 OX를 문자열로 입력받기
for (int i = 0; i < n; i++) {
int score = 0;
// 0보다 크고 80보다 작은 문자열 생성
char arr[80];
scanf("%s", arr);
// 입력받은 문자열의 길이 strlen(a)만큼을 반복문으로 사용하고 if문을 사용하여 각 배열에 저장된 O or X를 판독하기
for (int j = 0; j < strlen(arr); j++) {
// 가장 먼저 선언되어야 할 X일 경우 아무것도 하지 않고 넘어간다.
if (arr[j] == 'X') {
continue;
}
// 두 번째로 선언되어야 할 if문은 'O'일 경우 점수를 증가시킬 수 있어야 한다.
else if (arr[j] == 'O') {
// if문 내에서 score를 선언할 경우 매 if문마다 초기화되므로 상위 개념인 for문에 int score를 선언하고 score++로 1 증가시킨다.
score++;
// j를 기준으로 이전 문자열이 O일 경우 1씩 추가 점수를 부여해야하기에 for문을 사용하여 이전 문자열을 찾아내지만 X를 발견하면 중단하는 반복문을 작성한다.
// j - 1이 0일 경우까지 전부 찾아내야하므로 int k를 j - 1로 지칭하여 점점 감소하는 반복문을 작성한다.
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
// 가장 먼저 들어가야하는 경우는 X를 찾아낼 경우 for문을 그만 돌리고 나오는 것이다.
if (arr[k] == 'X') {
break;
}
// 그 다음으로는 O일 경우 추가 점수를 주어야하는데 이 추가 점수가 몇 점일지 모르기 때문에 int sum이라는 함수를 추가하여 거기에 더해놓고
// for문이 끝날 때 score에 합산하는 방식을 사용한다. 그러면 만약 OOOO(마지막 O가 j라면)
/*
1 1 1
1 1
1
+ 맨 처음 j가 도는 함수에서 score++로 1점이 더해지기 때문에
4 + 3 + 2 + 1점이 완성되는 방식으로 계산할 수 있게 된다.
*/
else if (arr[k] == 'O') {
// int sum은 if마다 초기화되는게 아니라 해당 for문 내에서는 값이 유지되어야하기에 for문 바로 아래에 선언한다.
// 그리고 O일 경우마다 sum에 ++로 더해주고 그 값을 for문이 끝날 때, score에 합산한다.
sum++;
}
score += sum; // 주의
}
}
// 마지막으로 O or X가 아닐 경우 전부 예외처리를 하고 즉시 프로그램을 종료시킬 수 있도록 변수를 차단한다.
else
return 0;
}
// 모든 연산이 끝난 후 score값을 프린트한다.
printf("%d\n", score);
}
}
2차 결과
5
OOXXOXXOOO
10
OOXXOOXXOO
9
OXOXOXOXOXOXOX
7
OOOOOOOOOO
55
OOOOXOOOOXOOOOX
30
미흡했던 점
- int score = 0;의 선언과 pritnf("%d", score); 명령어를 테스트 케이스의 갯수마다 반복해야하는데 (int i 반복문마다 해야하는데)
문자열의 길이만큼 반복되는 반복문(int j 반복문)에 넣어놓으니 당연히 X일 경우 실행중지하고 O일 경우 해당 점수를 계산하여
반복적으로 출력했던 것이다.
개선 방안
- 각 반복문 및 모든 명령어, 함수 사용에 있어서 어느 부분에서 정의되어야하는지 위치를 정확히 알고 사용한다.
최종 코드
#include <stdio.h>
#include <string.h>
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int score = 0;
char arr[80];
scanf("%s", arr);
for (int j = 0; j < strlen(arr); j++) {
if (arr[j] == 'X') {
continue;
}
else if (arr[j] == 'O') {
score++;
for (int k = j - 1; k >= 0; k--) {
int sum = 0;
if (arr[k] == 'X') {
break;
}
else if (arr[k] == 'O') {
sum++;
}
score += sum;
}
}
else
return 0;
}
printf("%d\n", score);
}
}
백준 실행 결과

'C > BaekJoon' 카테고리의 다른 글
[C] 백준 1977 - 완전제곱수 | BaekJoon (0) | 2023.08.01 |
---|---|
[C] 백준 2920 - 음계 | BaekJoon (0) | 2023.07.28 |
[C] 백준 2750 - 수 정렬하기 (순차 정렬) | BackJoon (0) | 2023.07.22 |
[C] 백준 2750 - 수 정렬하기 (선택 정렬) | BackJoon (0) | 2023.07.22 |
[C] 백준 2750 - 수 정렬하기 (삽입 정렬) | BackJoon (0) | 2023.07.21 |