题意:给出一个x 可以做两种操作 ①sqrt(x) 注意必须是完全平方数 ② x*=k (k为任意数) 问能达到的最小的x是多少
思路: 由题意以及 操作 应该联想到唯一分解定理 经过分析可以知道 ②操作最多使用一次 将x分解成一系列素数乘积的时候 只要看最高幂次离哪个二的幂近(只取上界)
并且把所以素因子都凑成找到的这个二的幂 只要x*=k一步就可以凑成 然后一直操作①模拟即可 而如果刚好全部都相等并且都是2的幂次 那么直接一直操作①模拟即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e6+5; 5 int fac[maxn],mi[maxn]; 6 int solve(int x){ 7 ll tmp=1; 8 for(int i=0;;i++){ 9 if(tmp>=x){ 10 return i; 11 } 12 else tmp<<=1; 13 } 14 } 15 map<ll,int>mp; 16 int main(){ 17 int n; 18 scanf("%d",&n); 19 ll la=1; 20 for(int i=1;i<=1000;i++){ 21 la<<=1; 22 if(la>10000000)break; 23 mp[la]=1; 24 } 25 if(n==1){ 26 cout<<1<<" "<<0<<endl; 27 return 0; 28 } 29 int flag=1; 30 long long ans=1; 31 for(int i=2;i<=n;i++){ 32 if(n%i==0){ 33 fac[flag]=i; 34 ans*=i; 35 while(n%i==0){ 36 n/=i; 37 mi[flag]++; 38 } 39 flag++; 40 } 41 } 42 int maxnum=0; 43 int cnt=0; 44 int ok=0; 45 for(int i=1;i<flag;i++){ 46 maxnum=max(maxnum,mi[i]); 47 if(mp[mi[i]]!=1)ok=1; 48 if(i>1&&mi[i]!=mi[i-1])ok=1; 49 } 50 if(maxnum==1){ 51 cout<<ans<<" " <<0<<endl; 52 return 0; 53 } 54 if(maxnum&1)maxnum++; 55 if(ok)cnt++; 56 // cout<<maxnum<<endl; 57 cnt+=solve(maxnum); 58 cout<<ans<<" "<<cnt<<endl; 59 return 0; 60 }