문제 번역
하나의 숫자 $N$을 입력받습니다. $N$을 $X$진수로 변환했을 때, 팰린드롬이 되는 모든 $X$값을 출력합니다. 만약 이러한 $X$값이 없다면 *을 출력합니다.
step 1
더보기
$N$이 2일 땐 *을 출력합니다. 그 외의 경우에는 $N-1$진수로 변환하면 항상 $11_{(N-1)}$이 나오므로 답이 1개 이상 존재합니다.
변환 결과가 2자리인 경우와 3자리 이상인 경우로 구분해 보겠습니다. 3자리 이상인 경우부터 해결하겠습니다.
3자리 이상인 경우에는 직접 계산합니다. $X$를 2부터 시작하여 $X$진수로 변환한 후 팰린드롬 여부를 확인합니다. $X>=\sqrt{N}$ 일 때 2자리가 되므로 이 과정은 $O( \sqrt{N} )$만큼 걸립니다.
step 2
더보기
- 2자리인 경우 $X>=\sqrt{N}$ 입니다. 두번째 자리에 $ \sqrt{N} $보다 큰 수가 들어가면 계산 결과가 $N$을 넘어갑니다.
- 변환 결과가 팰린드롬이므로 첫번째 자리와 두번째 자리가 같아야 합니다.
그렇다면 변환 결과가 $11, 22, ..., \sqrt{N} \sqrt{N} $을 만족하는 진수가 있는지 확인하면 됩니다.
결과가 $yy$라고 하면 $y*X+y=N, X=\frac{N-y}{y}$가 정수인지 확인합니다. 이때 $X$진수에는 $0$부터 $X-1$까지의 수만 들어갈 수 있으니 $ \frac{n-y}{y} > y$인지도 확인해 줍니다. 이 과정 역시 $O( \sqrt{N} )$에 해결할 수 있습니다.
코드
더보기
#define _CRT_SECURE_NO_WARNINGS
#define ll long long
#include <cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<math.h>
#include<string.h>
using namespace std;
ll b[100],d[3000000],dcnt=0;
int main() {
ll n, i;
scanf("%lld", &n);
if (n == 2) {
printf("*");
return 0;
}
for (i = 2;i <= n;i++) {
ll cnt = 0,ii=n;
while (ii != 0) {
cnt++;
b[cnt] = ii % i;
ii /= i;
}
if (cnt == 2) break;
ll s = 1, e = cnt;
while (s < e) {
if (b[s] != b[e]) break;
s++; e--;
}
if (s >= e) {
dcnt++;
d[dcnt] = i;
}
}
ll tmp = sqrt(n);
for (i = 1;i<=tmp;i++) {
if (i * i == n) break;
if ((n - i) % i == 0) {
if ((n - i) / i <= i) break;
dcnt++;
d[dcnt] = (n - i) / i;
}
}
sort(d, d + dcnt+1);
for (i = 1;i <= dcnt;i++) printf("%lld ", d[i]);
return 0;
}
'PS - 알고리즘' 카테고리의 다른 글
8155 - Postering (0) | 2024.05.20 |
---|---|
네트워크 플로우 (0) | 2024.05.10 |
백준 1118 - 색칠 2 (0) | 2024.05.05 |
백준 31749 - 조작 (2) | 2024.04.27 |
백준 31741 - 구간 덮기 (0) | 2024.04.21 |