您的位置:首页 > 其它

lightOJ 1220 Mysterious Bacteria

2015-04-30 22:50 357 查看
题目链接:http://lightoj.com/volume_showproblem.php?problem=1220

题目大意:给你一个整数n(可能为负数),让你求满足a^p=n的最大的p

思路:当n是正数时,直接对n进行素因子分解,在对它的素因子的个数进行gcd,比如12=2^2*3,gcd(2,1)就是最大的p;

当n是负数时,则p的值一定是奇数,因为一个数的偶数次方一定为整数,因此需要将它的素因子个数全都化为奇数。

#include<stdio.h>
#include<string.h>
const int MAXN=1000100;
bool vis[MAXN];
long long prime[MAXN/10];
int tot=0;
void getPrime()//求素数
{
for(long long i=2;i<MAXN;i++)
if(!vis[i])
{
prime[tot++]=i;
for(long long j=i*i;j<MAXN;j+=i) vis[j]=true;
}
}
int a[1000];//保存素因子
int b[1000];//保存素因子的个数
int cnt;
void sbreak(long long n){//进行素因子分解
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cnt=0;
for(int i=0;prime[i]*prime[i]<=n;i++){
if(n%prime[i]==0){
a[cnt]=prime[i];
while(n%prime[i]==0){
b[cnt]++;
n/=prime[i];
}
cnt++;
}
}
if(n!=1){
a[cnt]=n;
b[cnt++]=1;
}
}

int gcd(int a,int b) //求最大公约数
{
return b?gcd(b,a%b):a;
}

int main(){
int T,ans,kase=0,flag;
long long n;
getPrime();
scanf("%d",&T);
while(T--){
flag=1;//标志,判断n是正数还是负数
scanf("%lld",&n);
if(n<0) n=-n,flag=0;
sbreak(n);
int t=b[0];
if(!flag){//如果n是奇数
if(t%2==0){
while(t%2==0) t/=2;
}
for(int i=0;i<cnt;i++){//将它的素因子的个数化为奇数
if(b[i]%2==0){
while(b[i]%2==0) b[i]/=2;
}
t=gcd(t,b[i]);
}
}
else for(int i=0;i<cnt;i++) t=gcd(t,b[i]);
printf("Case %d: %d\n",++kase,t);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息