题目链接:http://codeforces.com/contest/1062/problem/B
题意:给你一个n,你有如下两种操作:
1. n *= x (x为正整数)
2. n = 根号下n (根号n 为 正整数)
问这个n最小能变成多少,最少的操作次数为多少。
题解:我们需要理解一下开方的操作。比如20 = 2*2*5。我们发现我们只需要乘个5就能让20变成100,从而进行开方,得到答案是10。所以这里我们需要明白,想开放,必须所有因子个数为2的次幂。所以我们这里有了初步的思路,因子个数2的次幂化。
我们还需要明白,n可以乘任何数字。我们可以让n一次性到位,然后进行操作2即可。这样保证了数量最少。
比如 2*2*2*3*5。
我们先把它变成 2*2*2*2*3*3*3*3*5*5*5*5
然后连续开方2次。
操作数量为3.是最小的。
所以代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int book[maxn];
queue<int>q;
int main(){
int n;
scanf("%d",&n);
int ans = 1;
int cnt = 0;
int count = 1;
int num = 0;
int temp = n;
for( int i = 2 ; i <= n ; i ++){
while(temp % i == 0){
if(!book[i]) ans *= i;
book[i] ++;
temp /= i;
}
if(book[i]) q.push(book[i]);
cnt = max(book[i],cnt);
}
if(cnt == 1){
printf("%d 0\n",ans);
return 0;
}
while(count < cnt){
num++;
count <<= 1;
}
int flag = 0;
while(!q.empty()){
int now = q.front();
q.pop();
if(now != count) {
flag = 1;
break;
}
}
if(flag) num++;
printf("%d %d\n",ans,num);
return 0;
}