Problem Solving/BOJ(백준)
[BOJ]백준 17252/17253번: 삼삼한 수, 삼삼한 수2
이진2
2020. 4. 30. 14:46
https://www.acmicpc.net/problem/17252
17252번: 삼삼한 수
첫째 줄에 2,147,483,647보다 작거나 같은 음이 아닌 정수 N이 입력된다.
www.acmicpc.net
3의 거듭제곱인 수들을 중복해서 사용하지 않고 더해서 삼삼한 수 X가 될 수 있는지 구하는 문제
중복이 허용되지 않는 조건때문에 단순한 재귀함수로 구현가능했다
예제1에서, X가 109일 경우 109보다 작은 81까지 배열에 저장해준다
index | 0 | 1 | 2 | 3 | 4 | |
n[index] | 1 | 3 | 9 | 27 | 81 | |
include | O | X | X | O | O | - |
① 일단 X보다 작은 3의 거듭제곱 수들을 순서대로 배열에 저장하고
② 재귀함수를 호출, 내림차순으로 배열을 돌면서 그 숫자를 더할지or안더할지를 호출해준다
③ 모든 경우의 수에서 한 번이라도 x가 완성되면 true 반환
#include <cstdio>
int x, n[21], i=1, t = 1;
bool func(int dep, int num) {
if (!dep)return num==x;
return func(dep - 1, num + n[dep]) || func(dep - 1, num);
}
int main() {
scanf("%d", &x);
for (; i < 21&&t <= x; i++, t *= 3)n[i] = t;
printf("%s", func(i-1, 0)&&x ? "YES" : "NO");
return 0;
}
+하지만 아주 간단한 풀이가 있었다
그것은 바로 숫자를 3진수로 변환해서 각 자리 숫자가 0,1 인지만 확인하면 되는것 ^-T
ex. 109(10) -> 1101(3), 298 -> 10201(3)
삼삼한수(17252) 풀이:
#include <cstdio>
int main() {
int x;
scanf("%d", &x);
if(!x) { printf("NO"); return 0; }
while (x) {
if (x % 3 > 1) { printf("NO"); return 0; }
x /= 3;
}
printf("YES");
return 0;
}
삼삼한수2(17253) 풀이:
#include <cstdio>
int main() {
long long x;
scanf("%lld", &x);
if(!x) { printf("NO"); return 0; }
while (x) {
if (x % 3 > 1) { printf("NO"); return 0; }
x /= 3;
}
printf("YES");
return 0;
}