devmoon

[C++] 백준 8111 : 0과 1 본문

알고리즘/Baekjoon Online Judge

[C++] 백준 8111 : 0과 1

Orca0917 2021. 10. 14. 10:54

1. 문제 출처

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

 

8111번: 0과 1

각각의 테스트 케이스마다 N의 배수이면서, 구사과가 좋아하는 수를 아무거나 출력한다. 만약, 그러한 수가 없다면 BRAK을 출력한다.

www.acmicpc.net

 

 

 

 

2. 문제 접근

N이 주어졌을 때, 100 자릿수 이하인 N의 배수를 구하는 데에는 시간도 매우 많이 걸리고, 해당 수를 담을 자료형도 long long으로 부족하기 때문에 string연산으로 해결을 해줘야 한다. 따라서 반대로, 1과 0으로 이루어진 수들을 작은 자리 수부터 생성을 하고, 그 수가 N의 배수인지 (N)으로 나눈 나머지가 0인지) 확인만 해주면 되었다.

 

 

 

 

1과 0으로 이루어진 100자리의 수 역시 매우 큰 수 이므로, 나머지 연산을 활용해야만 했다. 1과 0으로 이루어진 수를 생성하기 위해서 BFS를 사용하여 1 > 10, 11 > 100, 101, 110, 111 > ... 과 같이 생성을 하였고, 생성이 된 수마다 앞에서 말한 나머지 연산을 사용하였다. 이렇게 생성이 된 수가 0이 되었다면, 그 수는 입력으로 주어진 N으로 나누어 떨어지므로 해당 수에 대한 정답을 출력하면 되었다.

 

 

 

 

지속적으로 나머지 연산을 진행하기 때문에, 원래의 값도 같이 저장하게 pair<int, string>으로 선언을 진행하였다.

 

 

 

 

 

3. 코드

#include <bits/stdc++.h>

using namespace std;

int testcase, n, nx[2];
bool visited[20001];
string ns[2];

void bfs() {
    queue<pair<int, string>> q;
    q.push({1, "1"});
    visited[1] = true;
    
    while (!q.empty()) {
        int x = q.front().first;
        string s = q.front().second;
        q.pop();

        if (x == 0) {
            cout << s << "\n";
            return;
        }

        nx[0] = (x * 10) % n;
        ns[0] = s + "0";

        nx[1] = (x * 10 + 1) % n;
        ns[1] = s + "1";

        for (int i = 0; i < 2; ++i) {
            if (visited[nx[i]]) continue;
            visited[nx[i]] = true;
            q.push({nx[i], ns[i]});
        }
    }

    cout << "BRAK\n";
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> testcase;
    while(testcase--) {
        cin >> n;
        memset(visited, false, sizeof(visited));
        if (n == 1) cout << "1\n";
        else bfs();
    }

    return 0;
}
Comments