算法训练 素因子去重
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个正整数n,求一个正整数p,满足p仅包含n的所有素因子,且每个素因子的次数不大于1
输入格式
一个整数,表示n
输出格式
输出一行,包含一个整数p。
样例输入
1000
样例输出
10
数据规模和约定
n<=10^12
样例解释: n = 1000 = 2 3 ∗ 5 ∗ 3 , p = 2 ∗ 5 = 10 n=1000=2^3*5*3,p=2*5=10 n=1000=23∗5∗3,p=2∗5=10
很少写的前言:
这个粗心的出题人 ̄へ ̄,不知道大家有没有注意到样例解释。
n
=
1000
=
2
3
∗
5
∗
3
,
p
=
2
∗
5
=
10
n=1000=2^3*5*3,p=2*5=10
n=1000=23∗5∗3,p=2∗5=10。
本来我是明白这道题的,去掉素因子中重复的,那
2
∗
2
∗
2
∗
3
∗
5
2*2*2*3*5
2∗2∗2∗3∗5也应该是
2
∗
3
∗
5
2*3*5
2∗3∗5啊,为什么是
2
∗
5
2*5
2∗5。
我当时就蒙了,没看明白规则到底是什么。后来我和同学讨论这道题的时候,讲到
1000
=
2
∗
2
∗
2
∗
5
∗
5
∗
5
1000=2*2*2*5*5*5
1000=2∗2∗2∗5∗5∗5才反应过来,原来是样例解释写错了,不是
2
3
∗
5
∗
3
2^3*5*3
23∗5∗3,而是
2
3
∗
5
3
2^3*5^3
23∗53!(╬ ̄皿 ̄)=○#( ̄#)3 ̄)。出题人,希望你能更正一下样例解释,不要再误导同学们了!
分析:这道题和因式分解很像,就是求一个数的所有素因子。和因式分解不同的是,这道题并不是输出所有的素因子,而是将素因子中重复的去掉,输出剩余素因子的积。
例:
n
=
1000
=
2
∗
2
∗
2
∗
5
∗
5
∗
5
n=1000=2*2*2*5*5*5
n=1000=2∗2∗2∗5∗5∗5,去掉重复的,素因子有2和5,所以
p
=
2
∗
5
=
10
p=2*5=10
p=2∗5=10。
而 去掉重复 的 唯一性,刚好符合集合的特性,所以我为了偷懒,直接将素因子用集合set的方式存储了( ̄︶ ̄)↗,最后输出他们的乘积。
温馨提示,注意数据范围,要用long long哦~
代码如下:
#include <iostream>
#include <set>
using namespace std;
set<long long> a;
//求集合a中的数的乘积
long long fun2()
{
long long res = 1;
for(set<long long>::iterator it = a.begin(); it != a.end(); it++)
{
res *= *it;
}
return res;
}
//和数返回最小因数, 素数返回0
long long fun1(long long num)
{
for(long long i = 2; i * i <= num; i++)
{
if(num % i == 0) return i;
}
return 0;
}
//求num的所有素因子
void fun(long long num)
{
long long temp;
while(temp = fun1(num))
{
a.insert(temp);
num /= temp;
}
a.insert(num);
}
int main()
{
long long num;
cin >> num; //输入
fun(num); //计算
cout << fun2() << endl; //输出
return 0;
}