HDU6623 2019杭电多校第四场1010 Minimal Power of Prime
题意:给一个数,将其分解为若干个质因数的乘积,问:其中重复出现次数最少的个数是多少。如:36 = 2 * 2 * 3 * 3,2出现两次,3 出现两次,最少的还是两次,输出2.
PS:鬼知道这么短一道题目怎么有这么长的意思,要不是队友想出来,我就炸了
题解:分析一下,将数分为小于1e4的与大于1e4的数。
A:当输入的数小于1e4,直接判断1e4以内所有的素数,看哪个质因数出现的次数最少。
B:当输入的数大于1e4,1e18最大就是1e4的4次幂(5次幂就超出了),所以当数大于1e4,最多就只能是一个大于1e4的一个质因数的4次方;所以将这个大于的数,先去在1e4内的质因数走一下,记录出现次数最少的质因数的次数,然后将除去那些质因数后的数开4次方根,3次方根,2次方根。看哪个有整数值,在跟之前的最少次数比较,选出新的最新次数,最后输出最小次数。当然如果4次,2次,3次均无解,就说明剩下的这个数为质因数,要输出1。
C:分为小于1e4的与大于1e4的数,只是为了方便分析。但在实际代码中,就不分开来写了,因为无论大于还是小于,都要在1e4的质数中走一下,所以可以直接合并在一起判断就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 10017;
bool prime[MAXN] = { 0 }; // 值为 false 表示素数,值为 true 表示非素数
int a[MAXN];
int tot = 0;
void init() {
for (int i = 2; i <= MAXN; i++) {
int f = 0;
for (int j = 2; j <= sqrt(i); j++) {
if (i%j == 0) {
f = 1;
break;
}
}
if (f == 0)
a[++tot] = i;
}
return;
}
int main() {
memset(prime, 1, sizeof(prime));
init();
/*for (int i = 2; i <= MAXN; i++) {
if (prime[i])
a[++tot] = i;
}*/
ll t;
scanf("%lld", &t);
while (t--) {
ll re;
scanf("%lld", &re);
int minn = 1e4 + 7;
a[1];
for (int i = 1; i <= tot; i++) {
if (re % a[i] == 0) {
int num = 0;
while (re%a[i] == 0)
re /= a[i], num++;
minn = min(num, minn);
}
}
if (re == 1 || minn == 1)
{
cout << minn << endl;
continue;
}
else {
long long two = powl(re, 0.5)+0.5; //+0.5其实就是一个向上取整的操作
long long three = powl(re, 1.0 / 3)+0.5;//不加会因为精度问题爆WA
long long four = powl(re, 0.25)+0.5;
int f = 0;
if (four*four*four*four == re) {
f = 1;
minn = min(minn, 4);
}
else if (two*two == re) {
f = 1;
minn = min(minn, 2);
}
if (three*three*three == re) {
f = 1;
minn = min(minn, 3);
}
if (f == 0)
minn = min(minn, 1);
}
cout << minn << endl;
}
return 0;
}