문제 : https://www.acmicpc.net/problem/9421
[알고리즘풀이]
1 ~ N 까지의 Prime 중 Happy Number를 만족하는 수를 찾아서 출력해야 한다.
-1) 소수 찾기
1 ~ N 까지의 Prime을 먼저 찾아야 되므로 에라토스테네스 체를 이용한다.
#define size 1000001
bool p[size];
long long i, j;
for (i = 2; i < size; i++) {
if (p[i] == false) {
for (j = (i * i); j < size; j += i)
p[j] = true;
}
}
-2) Happy Number 찾기
숫자 N에 대해 각 자릿수의 제곱을 더해가는 과정을 반복하다,
1이 되면 Happy Number이고, 1이 나오지 않고 Cycle에 갇힌다면 Un Happy Number이다.
따라서 우리는 각 자릿수의 제곱을 더해가는 과정을 반복하며, Cycle을 체크해줘야 된다.
이때, N의 다음 happy number는 모든 자릿값이 9일 때 최대를 갖는다. 또, N이 10^6보다 작거나 같으므로
Happy Number를 구해가는 과정에서 가장 큰 값은 81 * 6인 486을 넘어갈 수 없다.
따라서, bool 배열인 c 배열을 만들어줘서, 그동안 구해온 수들을 check 해주고 같은 수가 나오면 Cycle이 생겼다고 판단하면 된다.
#include<iostream>
#include<cmath>
using namespace std;
#define size 1000001
bool p[size];
bool c[487];
int get_happynumber(int p) {
int next = 0, l;
for(l = 1; ; l++)
if ((int)pow(10, l - 1) <= p && p < (int)pow(10, l)) {
break;
}
int end = l;
for (int j = 0; j < end; j++) {
int temp = (p % (int)pow(10, l)) / (int)pow(10, l - 1);
next += temp * temp;
l--;
}
return next;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
long long i, j;
for (i = 2; i < size; i++) {
if (p[i] == false) {
for (j = (i * i); j < size; j += i)
p[j] = true;
}
}
int n;
cin >> n;
for (int i = 2; i <= n; i++) {
int prime = i;
if (p[i] == false) {
for (int j = 0; j < 487; j++)
c[j] = false;
while (1) {
int next = get_happynumber(prime);
if (next == 1) {
cout << i << '\n';
break;
}
else if (c[next] == true) {
break;
}
else {
c[next] = true;
}
prime = next;
}
}
}
}
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ] 11650 - 좌표 정렬하기 ( sort 이용 ) (0) | 2019.10.04 |
---|---|
[BOJ] 2161 - 카드1 (0) | 2019.10.04 |
[BOJ] 1456 - 거의 소수 (0) | 2019.10.03 |
[BOJ] 1715 - 카드 정렬하기 (0) | 2019.10.02 |
[BOJ] 2225 - 합분해 (0) | 2019.10.01 |