프라임의 최소 전원
문제 해결 아이디어
히트 (\ {1 N ^ \ FRAC } {5} \) 내에 소수 테이블은, 각 N에 대해, 상기 제 분해 \ (N ^ \ FRAC를 {1 } {5} \) 의 분해 범위 이후의 소수 m이 1과 같으면 N m에, 대답이 \ (N ^ \ FRAC {1 } {5} \) 의 최소 개수 (K)의 내부에 소수 분해. 그렇지 않으면 고장을 계속하고 소수가보다 더 큰 파괴하는 데 사용됩니다 (^ \ FRAC이 {1 N \ } {5} \) , 이렇게 네 개의 소수의 최대 곱 이렇게 세 개의 사례 : \ (^ P . 4 \) , \ (P ^. 3 \) , \ (P ^ 2 \) , \ (P ^ 2 * Q ^ 2 \) 와 대답의 경우 (P는, Q (1)보다 더 \ (N ^ \ FRAC 5} {1} {\) ) 준비시킨다. 처음 두 경우에 각각 볼 (m ^ \ FRAC. 1 {{}}. 4 \) \ \ (m ^ \ FRAC. 1 {{}}. 3 \)은 사실상 세 4 개의 경우에 숫자이다 동일한 긴 모양의로 ({1m ^ \ FRAC \ } {2} \) 라인에 정수가 아닌, 처음 4는 없으며, 응답은 1이다.
다음 코드는
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int read(){
int res = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -res : res;
}
ll p(ll a, int b)
{
ll ans = 1;
for(int i = 1; i <= b; i ++)
ans *= a;
return ans;
}
int main()
{
int t;
t = read();
vector<int> vec;
for(int i = 2; i <= 4000; i ++){
bool flg = true;
for(int j = 2; j <= sqrt(i); j ++){
if(i % j == 0){
flg = false;
break;
}
}
if(flg)
vec.push_back(i);
}
while(t --){
ll n;
scanf("%lld", &n);
int ans = 100;
for(int i = 0; i < vec.size(); i ++){
int t = vec[i];
int cnt = 0;
while(n % t == 0){
n /= t;
++cnt;
}
if(cnt)
ans = min(ans, cnt);
}
if(n == 1)
printf("%d\n", ans);
else {
for(int i = 4; i >= 1; i --){
if(i == 1)
printf("1\n");
else {
ll x = max((ll)pow(n, 1.0/i) - 5, 1LL);
bool flg = true;
ll m = p(x, i);
while(m < n){
++ x;
m = p(x, i);
}
if(m == n){
printf("%d\n", min(ans, i));
break;
}
}
}
}
}
return 0;
}