※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 9457번 문제인 기하학문양이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/9457
9457번: 기하학문양
각 테스트 케이스마다 Rn을 10,007로 나눈 나머지와 Cn을 10,007로 나눈 나머지를 출력한다. Rn은 2 × n 직사각형 그리드에서 만들 수 있는 스패닝 트리의 개수, Cn은 2 × n 원형 그리드에서 만들 수 있
www.acmicpc.net
먼저
우선
이와 같은 그리드의 스패닝 트리들은 맨 오른쪽의 두 노드 및 연결된 에지를 삭제했을 때 n이 1 작은 경우의 스패닝 트리가 되거나 되지 않는 두 가지로 분류할 수 있다. 전자의 경우 n이 1 작은 경우의 스패닝 트리에 오른쪽의 에지 3개 중 2개를 고르는 경우의 수를 곱한 개수만큼 존재한다. 후자의 경우, 오른쪽의 에지 3개가 모두 스패닝 트리에 포함된 경우이고, 그 개수는 그리드의 윗변과 아랫변이 모두 존재하는 연속(contiguous)한 길이가 얼마냐에 따라 각각 그 값을 계산해낼 수 있음을 관찰할 수 있다. 다음 그림은 그리드의 오른쪽 끝부터 윗변과 아랫변이 모두 존재하는 연속한 최대 길이가 2인 스패닝 트리 중 하나의 일부를 나타낸 것으로, 이 모양을 포함하는(오른쪽에서 세번째 윗변이 포함되지 않음) 스패닝 트리의 개수는

위에서 구한 관계를 이용해
아래는 제출한 소스코드이다.
#define MOD 10007LL
#include <iostream>
using namespace std;
typedef long long ll;
ll R[50001], rsum;
ll C[50001], csum = 1;
int T, N;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
R[1] = 1;
for (ll i = 2; i < 50001; i++) {
R[i] = (R[i - 1] * 3 + rsum * 2 + 1) % MOD;
rsum = rsum + R[i - 1] % MOD;
}
C[1] = 1;
for (ll i = 2; i < 50001; i++) {
C[i] = (i * R[i] + i * 2 * csum) % MOD;
csum = (csum + R[i]) % MOD;
}
cin >> T;
while (T--) {
cin >> N;
cout << R[N] << ' ' << C[N] << '\n';
}
}
'BOJ' 카테고리의 다른 글
[BOJ 2016 // C++] 미팅 주선하기 (0) | 2023.10.03 |
---|---|
[BOJ 9464 // C++] 직사각형 집합 (1) | 2023.10.02 |
[BOJ 9460 // C++] 메탈 (0) | 2023.09.30 |
[BOJ 2318 // C++] 상사 찾기 (0) | 2023.09.29 |
[BOJ 11341 // C++] Eakspay igpay atinlay? (0) | 2023.09.28 |