题意:
给一个数n,可以将它乘任意数,或者开方,问你能得到的最小数是多少,并给出最小操作次数
思路:
能将这个数变小的操作只能是开方,所以构成的最小数一定是
$n = p_1*p_2*p_3*dots *p_m$ 其中$p_i$为不同的质数
由唯一分解定理,我们需要把初始的n通过乘法变成可以(多次)开方成上数的形式
不引入多余的质因子,就是最小的数
一次乘法(如果需要乘的话)+数次开方就是最小操作次数
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e6+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int main() { int n; scanf("%d", &n); if(n==1)return printf("1 0"),0; int mx = -1; int mn = maxn; int ans = 1; int p = 0; for(int i = 2; n > 1; i++){ if(n%i==0){ int c = 0; ans*=i; while(n%i==0){ n/=i; c++; } mn = min(mn, c); mx = max(mx, c); } } int v = 1; while(v < mx){ v*=2; p++; } if(v!=mn)p++; printf("%d %d",ans,p); return 0; }