본문 바로가기
알고리즘/백준

[cpp 알고리즘] 백준 9242 폭탄 해체

by sum_mit45 2024. 7. 4.
728x90
반응형

[백준] 9242 폭탄 해체 cpp 풀이

구현, 문자열, 파싱

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

 

문제 요약

### ### ### ### ### ### ### ### ### ###
***   * *** *** * * *** *** *** *** ***
* *   *   *   * * * *   *     * * * * *
* *   * *** *** *** *** ***   * *** ***
* *   * *     *   *   * * *   * * *   *
***   * *** ***   * *** ***   * *** ***

 

- 0부터 9까지 숫자를 5×3으로 나타내는 방법이다.

- 이렇게 숫자를 표현하였을 때, 6으로 나누어 떨어지면 "BEER!!"를, 그렇지 않으면 "BOMB!!"를 출력하면 된다.

- 올바르지 않은 숫자가 주어진 경우에는 "BOMB!!"를 출력하면 된다.

 

풀이 정리

1. 모든 숫자에 대해, 숫자 모양을 *이 있으면 1, 없으면 0으로 표현했다.

 

2. 문제 자체는 단순한데, "공백포함 전체 문자열 입력받기"를 어떻게 하는지 몰라서 꽤 오래 걸렸다. 

string input;
getline(cin, input);

 

- 처음에는 이렇게 입력을 받았는데, 그러다보니까 띄어쓰기 포함 한 줄 밖에 입력이 안되었다. 

string input;
getline(cin, input, '$');

 

- 그래서 위의 코드처럼 '$'가 나올 때까지 모든 입력을 받는 코드로 수정해주었다.

   개인적으로 XCODE에서 실행할 때는 $을 입력해서 끝냈지만, 백준에서는 이렇게 하고 $을 입력하지 않았는데도 맞을 수 있었다. 

   (왜인지,, 더 알아보기)

 

3. 그 이후에는 총 몇 글자가 있는지 계산하고, 그 글자마다 5*3을 읽어보고 기존의 숫자모양과 비교해서 해당 숫자를 판별했다.

- 한 줄의 길이 = 전체길이/5

- 총 글자 수 = 한줄의 길이/4

- 실제 입력은 5*3으로 계속 주어지는 것이 아니고, 숫자마다 공백이 있어서 5*4로 주어졌다. 

 

4. 유효한 모양의 숫자라면 3번 과정을 반복적으로 진행하고, 아니라면 "BOMB!!"을 출력하고, 종료했다.

 

5. 문자열에 전체 숫자를 하나씩 합친 후에, stoi() 함수를 활용하여 숫자로 변환해주었다. 그 후에 6의 배수인지 확인했다. 

C++ 코드

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

int arr0[15] = {1,1,1,1,0,1,1,0,1,1,0,1,1,1,1};
int arr1[15] = {0,0,1,0,0,1,0,0,1,0,0,1,0,0,1};
int arr2[15] = {1,1,1,0,0,1,1,1,1,1,0,0,1,1,1};
int arr3[15] = {1,1,1,0,0,1,1,1,1,0,0,1,1,1,1};
int arr4[15] = {1,0,1,1,0,1,1,1,1,0,0,1,0,0,1};
int arr5[15] = {1,1,1,1,0,0,1,1,1,0,0,1,1,1,1};
int arr6[15] = {1,1,1,1,0,0,1,1,1,1,0,1,1,1,1};
int arr7[15] = {1,1,1,0,0,1,0,0,1,0,0,1,0,0,1};
int arr8[15] = {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1};
int arr9[15] = {1,1,1,1,0,1,1,1,1,0,0,1,1,1,1};

int tmparr[15];
string input; //15*8 = 120
string num;

int main(){
     
    getline(cin, input, '$');
    int numcount = input.length()/5; //한줄개수
    
    for(int i=0; i<input.length()/20; i++){ //글자개수
        int index=0;
        for(int j=0; j<5; j++){
            for(int k=0; k<3; k++){
                char c = input[i*4+j*numcount+k];
                //cout << i*4+j*numcount+k << c << " ";
                if(c=='*'){
                    tmparr[index] = 1;
                }
                else{
                    tmparr[index] = 0;
                }
                index++;
            }
            //cout << "\n";
        }
        
    
        bool isnumber = false;
        for(int j=0; j<15; j++){
            if(j==14 && arr0[j] == tmparr[j]){
                num+='0';
                isnumber = true;
            }
            if(arr0[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr1[j] == tmparr[j]){
                num+='1';
                isnumber = true;
            }
            if(arr1[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr2[j] == tmparr[j]){
                num+='2';
                isnumber = true;
            }
            if(arr2[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr3[j] == tmparr[j]){
                num+='3';
                isnumber = true;
            }
            if(arr3[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr4[j] == tmparr[j]){
                num+='4';
                isnumber = true;
            }
            if(arr4[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr5[j] == tmparr[j]){
                num+='5';
                isnumber = true;
            }
            if(arr5[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr6[j] == tmparr[j]){
                num+='6';
                isnumber = true;
            }
            if(arr6[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr7[j] == tmparr[j]){
                num+='7';
                isnumber = true;
            }
            if(arr7[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr8[j] == tmparr[j]){
                num+='8';
                isnumber = true;
            }
            if(arr8[j] == tmparr[j]) continue;
            else break;
        }
        for(int j=0; j<15; j++){
            if(j==14 && arr9[j] == tmparr[j]){
                num+='9';
                isnumber = true;
            }
            if(arr9[j] == tmparr[j]) continue;
            else break;
        }
        if(!isnumber){
            cout << "BOOM!!";
            return 0;
        }
    }
    
//    cout << num << "\n";
    int tmp = stoi(num);
//    cout << tmp;
    if(tmp%6 == 0){
        cout << "BEER!!";
    }
    else{
        cout << "BOOM!!";
    }
    
    return 0;
}

 

- 하지만 길이가 꽤 길고, 더 줄이거나 간단하게 할 수 있을 것이라고 생각했다. 

C++ 코드(2)

- 숫자 모양을 3차원 배열로 만들어서 사용하고 함수를 이용해서 더 코드를 줄일 수 있었다. 

- 입력 부분도 getline을 사용하되 한 줄 씩 입력받아서 합치는 방법도 있었다.

- 또한 나는 string을 int로 바꾸는 방법을 활용했는데, 숫자*10을 해서 바로 숫자로 만들어서 사용하는 방법도 있었다. 

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

const char number[10][5][4] = {
    {"***", "* *", "* *", "* *", "***"},  // 0
    {"  *", "  *", "  *", "  *", "  *"},  // 1
    {"***", "  *", "***", "*  ", "***"},  // 2
    {"***", "  *", "***", "  *", "***"},  // 3
    {"* *", "* *", "***", "  *", "  *"},  // 4
    {"***", "*  ", "***", "  *", "***"},  // 5
    {"***", "*  ", "***", "* *", "***"},  // 6
    {"***", "  *", "  *", "  *", "  *"},  // 7
    {"***", "* *", "***", "* *", "***"},  // 8
    {"***", "* *", "***", "  *", "***"}   // 9
};

bool isValidDigit(const vector<string>& code, int pos, int& digit) {
    for (digit = 0; digit < 10; digit++) {
        bool match = true;
        for (int i = 0; i < 5 && match; i++)
            for (int j = 0; j < 3 && match; j++) {
                if (code[i][pos + j] != number[digit][i][j])
                    match = false;
			}
        if (match) return true;
    }
    return false;
}

int main() {
    vector<string> input(5);
    for (auto& row : input) getline(cin, row);
    
    int ans = 0;
    bool invalid = false;
    for (int i = 0; i < board[0].size(); i += 4) {
        int digit;
        if (!isValidDigit(input, i, digit)) {
            invalid = true;
            break;
        }
        ans = ans * 10 + digit;
    }
    cout << ((invalid || ans % 6 != 0) ? "BOOM!!" : "BEER!!") << "\n";
}
728x90
반응형