Problem Solving/BOJ

[백준 / BOJ] C++ 17215 볼링 점수 계산

nageune 2023. 3. 5. 15:07
728x90
반응형

17215번: 볼링 점수 계산

 

문제

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

 

17215번: 볼링 점수 계산

첫째 줄에 각 기회마다 소현이가 쓰러뜨린 볼링핀의 개수가 공백없이 주어진다. 이때 스트라이크는 S, 스페어는 P, 핀을 하나도 못 쓰러뜨린 것은 -으로 주어진다.

www.acmicpc.net

 

 

풀이

시키는 대로 구현하는 문제다. 볼링에 대한 규칙을 아는 사람이라면 문제도 안 읽고 쉽게 풀 수 있을 것 같다.

 

문자열의 각 문자를 탐색하며 숫자일 경우 점수를 더하고, P(스페어)인 경우 (10 - 이전 투구에서 친 점수)를 추가하고 다음 투구의 점수도 더해준다. S(스트라이크)인 경우 10점을 추가하고 다음 두 번의 투구 점수를 함께 더해준다. 여기서 주의할 점은 10프레임에 스트라이크 또는 스페어를 칠 경우, 단독으로 점수에 들어가지 않는 추가 투구가 있다는 것이다. 따라서 프레임 계산을 해줘야 한다.

 

스트라이크인 경우 바로 프레임을 1 증가시키고, 스페어인 경우에도 반드시 프레임이 종료되니 1 증가시켜 준다. 한 프레임 내 두 번의 투구 모두 숫자 점수인 경우를 위해 check 변수를 만들어 첫 투구를 하면 1, 두 번째 투구를 하면 다시 0으로 바꾸며 프레임 추가를 해줬다. 자세한 설명은 코드의 주석을 참고하길 바란다.

 

하고 보니 많은 조건 분기인 것 같기도..

 

코드

#include <bits/stdc++.h>
using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  int frame = 0, ans = 0, check = 0;
  string str;
  cin >> str;
  // 문자열에서 i번째 문자를 탐색 하며 10 프레임까지만 탐색
  for (int i = 0; frame < 10; i++) {
    if (str[i] >= 49 && str[i] <= 57) { // 숫자인 경우
      ans += str[i] - '0'; // 점수 추가
      if (check) { // 두 번째 투구인 경우
        check = 0; // 체크 0으로 초기화
        frame++; // 프레임 증가
      } else { // 첫 번째 투구인 경우
        check = 1; // 체크 1로 할당
      }
    } else if (str[i] == 'S') { // 스트라이크인 경우
      ans += 10; // 10점 추가
      frame++; // 프레임 증가
      for (int j = 1; j < 3; j++) { // 다음 두 번의 투구에 대한 탐색
        if (str[i + j] >= 49 && str[i + j] <= 57) { // 숫자인 경우
          ans += str[i + j] - '0'; // 점수 추가
        } else if (str[i + j] == 'S') { // 스트라이크인 경우
          ans += 10; // 10점 추가
        } else if (str[i + j] == 'P') { // 스페어인 경우
          if (str[i + j - 1] >= 49 && str[i + j - 1] <= 57) { // 이전 투구가 숫자면
            ans += 10 - (str[i + j - 1] - '0'); // 10 - 이전 투구 점수 추가
          } else { // 이전 투구가 '-' 즉, 거터라면
            ans += 10; // 10점 추가
          }
        }
      }
    } else if (str[i] == 'P') { // 스페어인 경우
      check = 0; // 체크 0으로 초기화
      frame++; // 프레임 증가
      if (str[i - 1] >= 49 && str[i - 1] <= 57) { // 이전 투구가 숫자면
        ans += 10 - (str[i - 1] - '0'); // 10 - 이전 투구 점수 추가
      } else { // 이전 투구가 '-' 즉, 거터라면
        ans += 10; // 10점 추가
      }
      if (str[i + 1] >= 49 && str[i + 1] <= 57) { // 다음 투구가 숫자라면
        ans += str[i + 1] - '0'; // 점수 추가
      } else if (str[i + 1] == 'S') { // 다음 투구가 스트라이크라면
        ans += 10; // 10점 추가
      }
    } else { // 거터라면
      if (check) { // 두 번째 투구인 경우
        check = 0; // 체크 0으로 초기화
        frame++; // 프레임 증가
      } else { // 첫 번째 투구인 경우
        check = 1; // 체크 1로 할당
      }
    }
  }
  // 점수 출력
  cout << ans << '\n';
  return 0;
}
728x90
반응형