您的位置:首页 > 其它

pku1730 (整数分解素数+GCD,求幂pow)

2010-07-15 14:42 260 查看
http://acm.pku.edu.cn/JudgeOnline/problem?id=1730

题目大意:

给一个数n,求一个最大的q使得 n = a^q,其中a,q,n都是32位整数。(多组数据)

分析:只要将n进行素因子分解,把所有素因子数目的gcd求出来就行。注意:n可能是负数,所以对于负数还需要将求出来的结果试除2,直到结果不是偶数才是最后负数的结果。

下面的代码是把整数n分解成素数幂的形式n=p1^t1*…*pk^tk;

#include<iostream>
using namespace std;
int res[1000][2];
__int64 n;
bool s[100010];
int prime[10000];
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
void Prime()//求素数
{
int i,j,k,t;
for (i=2;i<=100000;i+=2) { s[i]=0; s[i-1]=1; }
s[1]=0; s[2]=1;
for (i=3;i<=500;i+=2)
{
if (s[i])
{
k=2*i; t=i+k;
while (t<=100000) { s[t]=0; t=t+k; }
}
}
k=1; prime[1]=2;
for (i=3;i<=100000;i+=2)
{
if (s[i]==1) { k++; prime[k]=i; }
}
prime[0]=k;
}
/*int fun()		//整数分解 n=p1^t1*…*pk^tk
{						//不知道哪里错了~~wa了几次、
int maxn=-1,i;
int sum = 0;
for(i=1; i<=prime[0]; i++)
{
if(n % prime[i] == 0)
{
sum++;
res[sum][1] = prime[i];
res[sum][0] = 0;
while(n % prime[i] == 0)
{
res[sum][0]++;
n /= prime[i];
}
}
}
return sum;
}
*/
int fun()		//整数分解 n=p1^t1*…*pk^tk
{
int i,s,k=0;
for (i=1; i<=prime[0]; i++)
{
s=0;
while(n%prime[i]==0)
{
s++;
n/=prime[i];
}
if (s>0)
{
k++;
res[k][1]=prime[i]; //存素因子
res[k][0]=s; 	    //存幂
}
if (n==1) break;
if (n/prime[i]<prime[i])
{
k++;
res[k][1]=n;
res[k][0]=1;
n=1;
break;
}
}
res[0][1]=res[0][0]=k;
return k;
}
int main()
{
int i,ans,sum,flag;
Prime();
while(scanf("%I64d",&n) && n)
{
flag = 0;
if(n<0)		//负数~~~
{
n = -n;
flag = 1;
}
sum = fun();
ans = res[1][0];
for(i=2; i<=sum; i++)
ans = gcd(ans,res[i][0]);
if(flag && ans % 2 == 0)	//n是负数,多一步处理、
{
while(ans % 2==0)
ans /= 2;
printf("%d/n",ans);
}
else
printf("%d/n",ans);
}
return 0;
}


下面的代码是用pow()函数写的,但是用这个函数要注意精度的问题,看了discuss之后才知道精度要设为1e-12,才能AC~~

#include<iostream>
#include<cmath>
using namespace std;
#define maxn 1000
#define IP 1E-12	//主要是精度的问题~
__int64 n;
double tep1,tep2;
void fun()
{
int  i,start=32,flag=1;	//整数情况flag=1;
if(n<0)
{
start=31;
flag = 2;	//负数情况flag=2;
n = -n;
}
double p;
for(i=start; i>=1; i-=flag)
{
p = pow(n*1.0, 1.0/i);
tep1 = floor(p);	//向下取整
tep2 = ceil(p);		//向上取整
//cout<<abs(p-tep1)<<endl;	0	abs(x):x为整数;
//cout<<fabs(p-tep1)<<endl;	0. ~~	fabs(x): x为浮点数;求绝对值;
if(fabs(p - tep1) < IP || fabs(tep2 - p) <= IP)
{

printf("%d/n",i);
break;
}
}
}
int main()
{
while(scanf("%I64d",&n) && n)
{
fun();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: