[백준] Baekjoon Online Judge
문제
정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.
- 1+1+1+1
- 1+1+2
- 1+2+1
- 2+1+1
- 2+2
- 1+3
- 3+1
이를 사전순으로 정렬하면 다음과 같이 된다.
- 1+1+1+1
- 1+1+2
- 1+2+1
- 1+3
- 2+1+1
- 2+2
- 3+1
정수 n과 k가 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법 중에서 k번째로 오는 식을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정수 n과 k가 주어진다. n은 양수이며 11보다 작고, k는 231-1보다 작거나 같은 자연수이다.
출력
n을 1, 2, 3의 합으로 나타내는 방법 중에서 사전 순으로 k번째에 오는 것을 출력한다. k번째 오는 식이 없는 경우에는 -1을 출력한다.
풀이
#include <iostream>
#include <string>
using namespace std;
int n, k, cnt = 0;
void dfs(int sum, string s);
void dfs(int sum, string s) {
if (sum == n) {
if (++cnt == k) {
cout << s << '\n';
exit(0);
}
return;
}
for (int i = 1; i < 4; i++) {
if (sum == 0)
dfs(sum + i, s + to_string(i));
else if (sum + i <= n)
dfs(sum + i, s + "+" + to_string(i));
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
dfs(0, "");
cout << "-1\n";
return 0;
}
void dfs(int sum, string s) {
if (sum == n) {
if (++cnt == k) {
cout << s << '\n';
exit(0);
}
return;
}
for (int i = 1; i < 4; i++) {
if (sum == 0)
dfs(sum + i, s + to_string(i));
else if (sum + i <= n)
dfs(sum + i, s + "+" + to_string(i));
}
}
문제의 답을 찾는 함수이다. 백트래킹으로 합이 n이 되는 1, 2, 3으로 이루어진 식을 구하도록 했다. 이 때 sum으로 만들어진 식의 합을, s에 식을 다음 호출로 보내준다.
이러다 sum이 n과 같아진다면 cnt를 증가시킨다. 이 cnt로 해당 식이 몇 번째 식인지 알 수 있는데, cnt가 k와 같다면 원하는 식을 찾은 것이기에 s를 출력하고, 프로그램을 끝내도록 했다.
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
dfs(0, "");
cout << "-1\n";
return 0;
}
만약 k번째로 오는 식이 없다면 dfs()로 인한 프로그램 종료가 없기에 -1을 출력하게 된다.
'백준 > C++' 카테고리의 다른 글
[Baekjoon/C++] 4779번 - 칸토어 집합 (0) | 2023.09.09 |
---|---|
[Baekjoon/C++] 15988번 - 1, 2, 3 더하기 3 (0) | 2023.09.08 |
[Baekjoon/C++] 28444번 - HI-ARC=? (0) | 2023.09.06 |
[Baekjoon/C++] 16194번 - 카드 구매하기 2 (0) | 2023.09.03 |
[Baekjoon/C++] 11052번 - 카드 구매하기 (0) | 2023.09.02 |