[SWEA] 1240 단순 2진 암호코드 (C++)

우리누리·2023년 11월 14일
0

👓 문제 설명

어떤 국가에서는 자국 내 방송국에서 스파이가 활동하는 사실을 알아냈다. 스파이는 영상물에 암호 코드를 삽입하여 송출하고 있었다. 스파이의 암호 코드에 다음과 같은 규칙이 있음을 발견했다.

1. 암호코드는 8개의 숫자로 이루어져 있다.

2. 올바른 암호코드는 (홀수 자리의 합 x 3) + (짝수 자리의 합)이 10의 배수가 되어야 한다.

ex) 암호코드가 88012346일 경우, ( ( 8 + 0 + 2 + 4 ) x 3 ) + ( 8 + 1 + 3 + 6) = 60은 10의 배수이므로 올바른 암호코드다.

ex) 암호코드가 19960409일 경우, ( ( 1 + 9 + 0 + 0 ) x 3 ) + ( 9 + 6 + 4 + 9) = 58은 10의 배수가 아니므로 잘못된 암호코드다.

이 암호코드들을 빠르고 정확하게 인식할 수 있는 스캐너를 개발하려고 한다.

스캐너는 암호코드 1개가 포함된 직사각형 배열을 읽는다.

직사각형 배열은 1, 0으로만 이루어져 있고, 암호코드 이외의 부분은 전부 0으로 주어진다.

암호코드에서 숫자 하나는 7개의 비트로 암호화되어 주어진다. 따라서 암호코드의 가로 길이는 56이다.

암호코드의 각 숫자가 암호화되는 규칙은 다음과 같다.

비정상적인 암호코드(가로 길이가 56이 아닌 경우, 아래 규칙대로 해독할 수 없는 경우)는 주어지지 않는다.

0 : 0 0 0 1 1 0 1
1 : 0 0 1 1 0 0 1
2 : 0 0 1 0 0 1 1
3 : 0 1 1 1 1 0 1
4 : 0 1 0 0 0 1 1
5 : 0 1 1 0 0 0 1
6 : 0 1 0 1 1 1 1
7 : 0 1 1 1 0 1 1
8 : 0 1 1 0 1 1 1
9 : 0 0 0 1 0 1 1


🚨 접근 방법

처음엔 0번째 인덱스부터 가로길이-7의 인덱스까지 sub_str을 이용하여
7자리 문자열을 추출한 후 암호 코드 정보와 일치하는지 판단하는 코드를 작성했다.
그러나 테스트 케이스 1개가 통과를 하지 못했다.
예외인 경우가 있나 살펴보니
0 : 0 0 0 1 1 0 1
1 : 0 0 1 1 0 0 1
이 경우에서 만약 1을 뽑아야 하는데 0 (0 0 1 1 0 0 1)처럼 1 앞에 0이 존재 하면
이를 0으로 처리해버린다.
그래서 맨 뒤의 인덱스부터 역순으로 뽑아서 해결했다.


🚈 풀이

#include<iostream>
#include<vector>
 
using namespace std;
 
int main(int argc, char** argv)
{
    int test_case;
    int T;
    int col, row;
    string row_line,arr[50];
    cin >> T;
 
 
    // 테스트케이스를 모두 확인해보니 앞에서부터 7자리를 탐색하면 안된다.
    // 0001101, 0011001인경우 무조건 앞에 0이 있으면 0001101로 지정하기 때문에
    // 뒤에서부터 탐색을 해야만 통과한다.
    for (test_case = 1; test_case <= T; ++test_case)
    {
        vector<int>v;
        int answer = 0;
        cin >> col >> row;
         
        for (int i = 0; i < col; i++) {
            cin >> row_line;
            arr[i] = row_line;
            // 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30
            for (int j = row-7; j >=0 ; j--) {
                if (arr[i].substr(j,7) == "0001101") {
                    j -= 6;
                    v.push_back(0);
                }
                else if (arr[i].substr(j,7) == "0011001") {
                    j -= 6;
                    v.push_back(1);
                }
                else if (arr[i].substr(j,7) == "0010011") {
                    j -= 6;
                    v.push_back(2);
                }
                else if (arr[i].substr(j,7) == "0111101") {
                    j -= 6;
                    v.push_back(3);
                }
                else if (arr[i].substr(j,7) == "0100011") {
                    j -= 6;
                    v.push_back(4);
                }
                else if (arr[i].substr(j,7) == "0110001") {
                    j -= 6;
                    v.push_back(5);
                }
                else if (arr[i].substr(j,7) == "0101111") {
                    j -= 6;
                    v.push_back(6);
                }
                else if (arr[i].substr(j,7) == "0111011") {
                    j -= 6;
                    v.push_back(7);
                }
                else if (arr[i].substr(j,7) == "0110111") {
                    j -= 6;
                    v.push_back(8);
                }
                else if (arr[i].substr(j,7) == "0001011") {
                    j -= 6;
                    v.push_back(9);
                }
                if (v.size() == 8)break;
            }
        }
        int comp=(v[1] + v[3] + v[5] + v[7]) * 3 + v[0] + v[2] + v[4] + v[6];
        if (comp % 10 == 0) {
            for (auto p : v) {
                answer += p;
            }
        }
        cout << "#" << test_case << " " << answer << "\n";
    }
    return 0;
}

0개의 댓글