2019 杭电多校 HDU - 6623

Minimal Power of Prime
题意:让你把一个数质因数分解,输出所有质因数指数的最小值。
这个题还是挺有意思的,解题思路也比较好玩。

思路:先预处理出10000以内的素数预处理出来。对于每一个 n ,我们先处理它10000以内的质因数,那么剩下的质因数的指数就不可能超过4,单独判断即可;

为什么不会超过4呢
当我们选出10000以内的所有质因数之后,那么剩下的因数必然大于10000,并且都是质因数,假设它是一个合数,那么一定可以被分解,分解出的小于10000的质数在之前就已经被处理了,所以这个时候就不可能存在了, 而 1 0 4 4 {10^{4}}^{4} 就是 1 0 16 10^{16} 了, 1 0 4 5 {10^{4}}^{5} 就是 1 0 20 10^{20} 了,所以必然不会超过4;
小提示:对于4次和二次的判断可以直接使用sqrt函数,而三次需要我们手写一个二分去判断,我尝试过使用pow函数,但是wr了,可见pow的进度还是存在问题的,相比之下sqrt就比较友好了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 10000 + 10;
ll n, t;
ll p[N], prime[N],cnt;
void init() {
	memset(prime,0,sizeof(prime));
	for (ll i = 2; i < N; i++) {
		if (!prime[i])p[cnt++] = i;
		for (ll j = i * 2; j < N; j += i)prime[j] = 1;
	}
}

ll slove(ll x) {
	ll L = p[cnt - 1], R = pow(x*1.0,1.0/3.0) + 10;
	while (L < R) {
		ll mid = L + R + 1 >> 1;
		if (mid*mid*mid > x)R = mid - 1;
		else L = mid;
	}
	return L;
}

int main() {
	init();
	scanf("%d",&t);
	while (t--) {
		scanf("%lld",&n);
		int ans = 100;
		for (ll i = 0; i < cnt; i++) {
			if (n < p[i])break;
			while (n%p[i] == 0) {
				int res = 0;
				while (n % p[i] == 0)n /= p[i], res++;
				ans = min(ans,res);
			}
		}
		if (n > p[cnt - 1]) {
			//ll k1 = pow(n,1.0/5.0);
			ll k2 = sqrt(sqrt(n*1.0));
			ll k3 = slove(n);
			ll k4 = sqrt(n*1.0);
			//if (k1*k1*k1*k1*k1 == n)ans = min(ans,5);
			if (k2*k2*k2*k2 == n)ans = min(ans,4);
			else if (k3*k3*k3==n)ans = min(ans,3);
			else if (k4*k4 == n)ans = min(ans,2);
			else ans = 1LL;
		}
		printf("%d\n",ans);
	}
	return 0;
}
发布了70 篇原创文章 · 获赞 5 · 访问量 7180

猜你喜欢

转载自blog.csdn.net/xiaonanxinyi/article/details/98728780