题意:给定数n,可进行两种操作:乘一个任意数x; 开方,( sqrt(n)必须为整数
输出可达最小值ans 及 最小操作数
一个数可分解成有限个质数的幂次相乘:n=p1^x1 * p2^x2 * p3^x3..., 则n的所有质因子的乘积即为ans
接下来就是找所有质因子和判断最小操作数了
从 i=2 开始 n的第一个因子必为质数,不断除该因子,减小n, 新得到n的第一个因子也必为质数, 重复,直至 i==n
咋找最小操作数捏,e.g. 40=2^3*5^1; ans=10, 能开方次数必为2的幂次, 这里幂次最大为3, 则要开方至少得*2得到2^4
so 问题解决了 最小操作数就是开方次数+乘数的次数
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<list> #include<set> using namespace std; typedef long long ll; typedef pair<ll,ll> p; typedef long double ld; #define mem(x) memset(x, 0, sizeof(x)) #define me(x) memset(x, -1, sizeof(x)) #define fo(i,n) for(i=0; i<n; i++) #define sc(x) scanf("%lld", &x) #define pr(x) printf("%lld ", x) #define pri(x) printf("%lld ", x) #define lowbit(x) x&-x const ll MOD = 1e18 +7; const ll N = 6e6 +5; map<ll,ll>mp; ll a[N]; int main() { ll i, j ,k, l=0; ll n, m, t; cin>>n; if(n==1) return cout<<1<<' '<<0<<endl, 0; ll ans=1, mx=0, mi=MOD; m=0; for(i=2; i<=n; i++) { ll co=0; if(n%i==0) ans*=i; while(n%i==0) n/=i, co++; mx=max(co,mx); if(co) { mi=min(mi,co); } while((1<<m)<co) m++; } //cout<<"m="<<m<<" mx="<<mx<<" mi="<<mi<<endl; if(mi!=mx || (1<<m)!=mx) m++; cout<<ans<<' '<<m<<endl; return 0; }