HDU6623 2019杭电多校第四场1010 Minimal Power of Prime

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
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;
}


你可能感兴趣的:(思维)