题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26932
Description
Dr. Mob has just discovered a Deathly Bacteria. He named it RC-01. RC-01 has a very strange reproduction system. RC-01 lives exactly x days. Now RC-01 produces exactly p new deadly Bacteria where x = bp (where b, p are integers). More generally, x is a perfect pth power. Given the lifetime x of a mother RC-01 you are to determine the maximum number of new RC-01 which can be produced by the mother RC-01.
Input
Input starts with an integer T (≤ 50), denoting the number of test cases.
Each case starts with a line containing an integer x. You can assume that x will have magnitude at least 2 and be within the range of a 32 bit signed integer.
Output
For each case, print the case number and the largest integer p such that x is a perfect pth power.
Sample Input
3
17
1073741824
25
Sample Output
Case 1: 1
Case 2: 30
Case 3: 2
Time Limit: 500MS | Memory Limit: 32768KB | 64bit IO Format: %lld & %llu |
思路:把x因式分解,写成x=prime1^p1+prime2^p2+.....;b是任意的,所以x=b^gcd(p1,p2,p3,p4.........);比如x=2^2 * 3^4 * 5^8,gcd(2,4,8)=2;
所以x=b^2,此时x=(2^1 * 3^2 * 5^4);这个gcd就是答案p;不过注意题目说x是32int范围内,32位是包括负数的,所以要处理负数,if(x<0) 将x变成正数去
分解因式,最后在答案中去掉所有2,因为负数不可能是一个数的偶数次方,也就是说b^p,p必须是奇数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<set>
#include<vector>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=(1<<17)+2333;
const int INF=0x3f3f3f3f;
typedef long long ll;
int pri[maxn],vis[maxn];
int a[maxn];
int tot;
void init()
{
tot=0;
memset(vis,0,sizeof vis);
for(int i=2;i<maxn;i++)
{
if(!vis[i])
pri[tot++]=i;
for(int j=0;j<tot && i*pri[j]<maxn;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)
break;
}
}
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
init();
int t;
cin>>t;
int kase=t;
while(t--)
{
ll x;
scanf("%lld",&x);
int tag=0;
if(x<0)
tag=1,x=-x;
int ans=0;
for(int i=0;i<tot;i++)
if(x%pri[i]==0)
{
int cnt=0;
while(x%pri[i]==0)
{
cnt++;
x/=pri[i];
}
if(ans==0)
ans=cnt;
else ans=gcd(ans,cnt);
if(x==1)
break;
}
if(x>1)
ans=1;
else
{
if(tag)
while(ans%2==0)
ans/=2;
}
printf("Case %d: %d\n",kase-t,ans);
}
return 0;
}