본문 바로가기
코딩과 알고리즘

백준알고리즘 8958번 풀이 &해설

문제

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.

"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.

OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 0보다 크고 80보다 작은 문자열이 주어진다. 문자열은 O와 X만으로 이루어져 있다.

출력

각 테스트 케이스마다 점수를 출력한다.

예제입력

5

OOXXOXXOOO

OOXXOOXXOO

OXOXOXOXOXOXOX

OOOOOOOOOO

OOOOXOOOOXOOOOX

예제출력

10

9

7

55

30

해설

이 문제는 콤보득점에 대한 점수획득을 계산하는 문제로 난이도는 쉬운 편입니다.

이를테면 한번 문제를 맞추면 1점이지만,

2번 연속으로 맞추면 2번째 맞춘 문제의 1점 외에도

콤보점수 1점이 더욱 추가되는 것이지요,

만약 3번 연속으로 맞추면 3번째 맞춘 문제의 1점 외에 더블콤보, 2점이 더 추가됩니다.

그러다 한번 문제를 틀리면 콤보점수는 초기화가 되고 다시 처음부터 세는 설정이 되는 그런 문제입니다.

우선 n이라는 변수를 선언하고 OX목록의 갯수가 몇번 입력이 주어지는지 횟수를 입력받는 부분부터 시작됩니다.

int n;

scanf("%d", &n);

OX문자열은 최대 80이긴 하지만, 간혹 출제자가 실수할 수도 있으리라는 가정으로 100문자의 문자배열을 잡아놓고 시작합니다.

혹시라도 실수를 하지 않을거라 가정하더라도 배열크기는 81로 잡아주셔야 합니다.

80문자 외에도 문자열의 끝을 나타내는 '\0' 문자가 한자리 더 잡아먹기 때문에

이 부분을 빼먹으면 다른 변수나 코드의 메모리 영역을 침범하기 때문에

프로그램 버그가 발생합니다. 크레이는 안전빵으로 100 바이트로 잡았습니다.

char ox[100];

그러면서 n번 문장 입력을 받으면서 바로 바로 결과를 계산해서 처리합니다.

for (int i = 0; i < n; ++i)

{

:

}

점수계산을 위해 총점 변수를 선언하고 콤보계산을 위한 변수도 선언합니다

처음에는 아무것도 맞춘게 없기 때문에 콤보점수는 0점이 됩니다.

for (int i = 0; i < n; ++i)

{

int score = 0;

int combo = 0;

띄어쓰기는 없기 때문에 단순히 scanf("%s", 문자열변수);로 OX문장을 받아오면 됩니다.

만일 중간에 띄어쓰기가 있을 경우 띄어쓰기 전까지만 받아오니 별도 처리를 해주어야 합니다. 다행히 이 문제는 띄어쓰기가 중간에 없는 문제입니다.

for (int i = 0; i < n; ++i)

{

:

scanf("%s", ox);

다음으로 ox문자열을 앞에서부터 1개씩 순서대로 처리합니다.

strlen(ox)는 ox문자열의 길이를 의미합니다.

ox문자열의 길이가 80바이트인 경우,

for 문 안에서 J=0부터 79까지를 반복합니다.

for (int i = 0; i < n; ++i)

{

:

for (int j = 0; j < strlen(ox); ++j)

{

:

}

OX문자열의 j번째 문자가 O인지 판단합니다.

for (int i = 0; i < n; ++i)

{

:

for (int j = 0; j < strlen(ox); ++j)

{

if (ox[j] == 'O') {

:

}

만약 O 라면 총점에 1점과 콤보점수를 더해줍니다.

처음 문제를 맞춘 경우 콤보점수는 0점이기 때문에 점수가 1점만 올라가지만

정답하나를 맞출때마다 콤보 점수가 1씩 올라가기 때문에 다음번에 정답을 맞추면 콤보점수가 더해져서 2점이 올라가고, 그 다음에 맞추면 3점이 되는 연속가산 득점을 얻게 됩니다.

for (int i = 0; i < n; ++i)

{

:

for (int j = 0; j < strlen(ox); ++j)

{

if (ox[j] == 'O') {

score += 1 + combo;

combo++;

그러나 문제를 틀릴 경우 점수는 얻지 못하고 콤보점수도 초기화되는 것이지요.

for (int i = 0; i < n; ++i)

{

:

for (int j = 0; j < strlen(ox); ++j)

{

if (ox[j] == 'O') {

:

}

else combo = 0;

OX문장의 모든 문자에 대한 검사를 마친 후에는 총점을 출력해줍니다.

for (int i = 0; i < n; ++i)

{

:

for (int j = 0; j < strlen(ox); ++j)

{

:

}

:

printf("%d\n", score);

그리고 다시 앞단계(아래 부분)로 돌아가 반복문을 계속해서 수행합니다.

for (int i = 0; i < n; ++i)

{

int score = 0;

int combo = 0;

:

}

 

#include <iostream>
#include <cstring>
#include <string>
using namespace std;

// 숫자의 갯수
void OX()
{
	int n;
	char ox[100];
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
	{
		int score = 0;
		int combo = 0;
		scanf("%s", ox);
		for (int j = 0; j < strlen(ox); ++j)
		{
			if (ox[j] == 'O') {
				score += 1 + combo;
				combo++;
			}
			else combo = 0;			
		}
		printf("%d\n", score);

	}

}

int main()
{
	OX();
	return 0;
}

크레이의 랭킹놀이 :)

14000대 곧 진입예정!