※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 8112번 문제인 0과 1 - 2이다.
문제는 아래 링크를 확인하자.

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

 

8112번: 0과 1 - 2

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

www.acmicpc.net

8111번 문제에서 T가 커지고 N이 작아진 문제이다.

 

8111번 풀이글에서의 풀이를 그대로 쓰면 긴 문자열을 계속 복사하는 데에는 문자열의 길이만큼의 시간복잡도가 필요하여 시간초과가 나므로 그 대신 백트래킹을 통해 답안을 구해주자.

 

각 "나머지" 별로, 그 나머지를 갖게 하는 최소의 숫자는 BFS의 탐색순서로 만들어진 BFS 트리를 따라 거꾸로 가는 것이므로 이를 이용해 백트래킹이 가능하다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

int ans[1000001];
int visited[1000001];
int parent[1000001];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N; cin >> N;
	while (N--) {
		memset(visited, 0, sizeof(visited));
		int x; cin >> x;
		if (x == 1) cout << 1 << '\n';
		else {
			queue<int> que;
			ans[1] = 1;
			que.push(1);
			while (!que.empty()) {
				int r = que.front(); que.pop();
				if (r == 0) {
					vector<int> vec;
					int temp = 0;
					while (temp != 1) {
						vec.emplace_back(ans[temp]);
						temp = parent[temp];
					}
					vec.emplace_back(1);
					if (vec.size() <= 100) {
						for (auto iter = vec.rbegin(); iter != vec.rend(); iter++) cout << *iter;
						cout << '\n';
					}
					else cout << "BRAK\n";
					break;
				}
				int rr = r * 10 % x;
				if (!visited[rr]) {
					visited[rr] = 1;
					ans[rr] = 0;
					parent[rr] = r;
					que.push(rr);
				}
				rr = (r * 10 + 1) % x;
				if (!visited[rr]) {
					visited[rr] = 1;
					ans[rr] = 1;
					parent[rr] = r;
					que.push(rr);
				}
			}
			if (!visited[0]) cout << "BRAK\n";
		}
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1202 // C++] 보석 도둑  (0) 2021.10.14
[BOJ 2583 // C++] 영역 구하기  (0) 2021.10.13
[BOJ 8111 // C++] 0과 1  (0) 2021.10.11
[BOJ 2800 // C++] 괄호 제거  (0) 2021.10.10
[BOJ 1595 // C++] 북쪽나라의 도로  (0) 2021.10.09

+ Recent posts