[백준] 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";
}
'알고리즘 > 백준' 카테고리의 다른 글
[cpp 알고리즘] 백준 4396 지뢰 찾기 (0) | 2024.07.08 |
---|---|
[cpp 알고리즘] 백준 17291 새끼치기 (0) | 2024.07.07 |
[cpp 알고리즘] 백준 1744 수 묶기 (0) | 2023.11.11 |
[cpp 알고리즘] 백준 1629 곱셈 (0) | 2023.11.10 |
[cpp 알고리즘] 백준 1780 종이의 개수 (0) | 2023.11.09 |