그래프
[백준] 2331. 반복수열 풀이
hch06
2025. 3. 6. 22:07
https://www.acmicpc.net/problem/2331
- D[1] = A
- D[n] = D[n-1]의 각 자리의 숫자를 P번 곱한 수들의 합
이고, 수열 D에서 반복적인 부분을 삭제하였을 때의 수열에 남게되는 수를 구하는 문제.
나는 이를 DFS를 통해 풀었다. (사실 단순히 한 방향으로 이루어지는 구조라서 재귀적인 방법으로 풀었다에 더 가깝다고 생각한다.)
우선 236197개의 요소를 가진 배열을 생성한다.
그 이유는 수열에서 나올 수 있는 최대 숫자가 9^2+9^2+9^2+9^2 = (9^2)*4 = 236197 이기 때문이다.
그 후 DFS함수를 이용해서 a의 각 자릿수의 p제곱한 값의 합을 저장한다.
이렇게 구한 합이 다음 수열의 값이 된다.
나중에 반복된 수열이 나오는지 확인해야 하므로 이를 저장해둔다.
(나는 check배열을 만들어서 다음 수열을 계산하며 나온 값에 해당하는 인덱스에 1 혹은 True값을 저장했다.)
다음 수열들을 계산해나가다가 이미 나온 수열값이 있다면 탐색을 종료한다.
최종적으로 현재까지 나온 수열의 개수(= check에 저장된 1 혹은 True의 개수)를 출력하여 문제를 해결한다.
C
더보기
#include <stdio.h>
#define MaxSize 10000
int record[MaxSize];
int check[236197];
void append(int v){
for(int i = 0; i < MaxSize; i++){
if(record[i] == 0) {
record[i] = v;
break;
}
}
}
int DFS(int v, int p){
check[v] = 1;
append(v);
int sum = 0;
while(v > 0){
int mtp = 1;
for(int i = 0; i < p; i++) mtp *= v % 10;
sum += mtp;
v /= 10;
}
if(check[sum] == 1) return sum;
else return DFS(sum, p);
}
int main() {
int a, p; scanf("%d %d", &a, &p);
int v = DFS(a, p);
int cnt = 0;
for(int i = 0; i < MaxSize; i++){
if(record[i] == v) {
printf("%d", cnt);
break;
}
cnt += 1;
}
}
Python
더보기
import sys
sys.setrecursionlimit(10 ** 6)
def DFS(v, p):
check[v] = True
record.append(v)
sum = 0
while v > 0:
sum += (v % 10) ** p
v //= 10
if check[sum] == True:
return sum
else:
return DFS(sum, p)
record = []
a, p = map(int, input().split())
check = [False for _ in range(236197)] # (9^5)*4
v = DFS(a, p)
cnt = 0
for i in record:
if i == v:
print(cnt)
break
cnt += 1