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

 

이번에 볼 문제는 백준 22662번 문제인 Pi is Three이다.
문제는 아래 링크를 확인하자.

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

 

글쓴이는 Stern-Brocot tree(Farey sequence)를 이용하여 문제를 해결하였다. 해당 개념을 알고 있다고 가정하고 풀이를 서술한다.

 

Farey sequence에서 인접한 두 항 \(L=\frac{A_1}{A_2}\)과 \(R=\frac{B_1}{B_2}\)이 사이에 원주율에서 3을 뺀 값 \(P\)을 포함하고 있다고 해보자. 이때, \(P-L\)과 \(R-P\) 중 작은 값보다 더 \(P\)에 가까운 분수의 분모는 Farey Sequence의 성질에 의해 \(A_2\) 및 \(B_2\)보다 큼을 관찰하자.

 

위 성질을 이용하면 Stern-Brocot tree를 따라 \(P\)에 가까운 분수를 찾아나가는 것으로 문제에서 요구하는 분수를 찾을 수 있게 된다. 이를 이용해 문제를 해결하자.

 

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

//stern-brocot tree
#include <iostream>
#include <cmath>
using namespace std;
typedef long double ld;
typedef long long ll;

const ld PI3 = acosl(-1) - 3;

ll A1 = 0, A2 = 1, B1 = 1, B2 = 1, C1, C2;
ld x;

void solve() {
	A1 = 0, A2 = 1, B1 = 1, B2 = 1;
	while (PI3 * A2 - A1 > x * A2 && B1 - PI3 * B2 > x * B2) {
		C1 = A1 + B1, C2 = A2 + B2;
		if (PI3 * C2 < C1) B1 = C1, B2 = C2;
		else A1 = C1, A2 = C2;
	}
	if (PI3 * A2 - A1 < x * A2) cout << A2 * 3 + A1 << '/' << A2 << '\n';
	else cout << B2 * 3 + B1 << '/' << B2 << '\n';
}

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

	cin >> x;
	while (x) {
		solve();
		cin >> x;
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 30679 // C++] 별 가두기  (0) 2024.05.18
[BOJ 16508 // C++] 전공책  (0) 2024.05.17
[BOJ 11690 // C++] LCM(1, 2, ..., n)  (0) 2024.05.15
[BOJ 19592 // C++] 장난감 경주  (0) 2024.05.14
[BOJ 20116 // C++] 상자의 균형  (0) 2024.05.13

+ Recent posts