题目大概意思 给你一个x 令 x=b^p 求最大的p
例如 81=9^2=3^4则p的值为 4
一看蒙啦,这怎么求啊,数据范围在2^32次方之内,纠结,这种题一定会有算法,
再看列出几个例子来
例如: x p
9=3*3 2
36=2*2*3*3 2
100=2*2*5*5 2
81=3*3*3*3=9*9 4
看出端倪儿来了没我来解释一下 9 36 100 81 都可以分解成素数之积 儿这些素数
个数的最大公约数就是p的值
有没有激动啦,终于理清思路了,开始写,用横扫千军之势写出代买为啥还是wa
气愤了,不写了,我明明没错啊,怎么就过不了呢。浏览一下大家的讨论,晕,该
题测试数据中含有令人气愤的负数,而负数是没有偶次根的
再改,将求出的素数的公约数,如果为负数,就除以2直到遇到奇数,再输出如果不
是负数直接输出;这下该对了吧,可惜天不从人愿,还是wa
这是为嘛捏,再随便溜达溜达,忽然发现一组数据,-2147483648 ,2147483648按
照常理来说结果应该等于31可惜我的程序输出的是1 无论怎样该都是1
检查一下,我发现一个问题
if(n<0)
n=-1;
或者 n=fabs((double)n);
这两种代码 如果n=-2147483648或者 --2147483648的话是不执行的,也就是说n就
算是-2147483648,执行绝对值运算以后还是-2147483648
我无语了,why!
但是abs(prime[i])>sqrt(fabs((double)n)) 是可以执行的而且结果是对的,那就
这样用吧;改过以后果然ac
注意问题:
1 负数问题
2 最大数问题
3 k个数的公约数问题
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define maxnum 50001
long pnum[maxnum];
long prime[maxnum];
long l,n;
void init()
{
long i,j;
memset(pnum,0,sizeof(pnum));
for(i=2;i<maxnum;i++)
{
for(j=2;j*i<maxnum;j++)
pnum[j*i]=1;
}
l=0;
for(i=2;i<maxnum;i++)
if(pnum[i]!=1)
{
prime[l]=i;
l++;
}
}
long gcd(long a,long b)
{
return b==0? a:gcd(b,a%b);
}
long solve(long n)
{
long i;
long x=n;
long len=0;
n=fabs((double)n);
memset(pnum,0,sizeof(pnum));
for(i=0;i<l&&n!=1&&n!=-1;i++)
{
if(abs(prime[i])>sqrt(fabs((double)n)))
break;
if(n%prime[i]==0)
{
while(n%prime[i]==0)
{
n/=prime[i];
pnum[len]++;
}
len++;
}
}
if(fabs((double)n)!=1)
{
pnum[len]++;
len++;
}
if(len==0)
return 1;
if(x<0)
for(i=0;i<len;i++)
while(pnum[i]%2==0)
pnum[i]/=2;
if(len<2)
return pnum[0];
long m=gcd(pnum[0],pnum[1]);
for(i=2;i<len;i++)
m=gcd(pnum[i],m);
if(x<0)
while(m%2==0)
m/=2;
return m;
}
int main()
{
init();
while(scanf("%ld",&n)!=EOF)
{
if(n==0) break;
printf("%ld\n",solve(n));
}
return 0;
}