我正在解决SPOJ的ETF问题。我正在使用eratosthenes方法筛来计算质数,然后使用Phi的基本定义,但是SPOJ给出了错误的答案。我在GCC编译器上测试了它,在那里提到了0到1000,000的范围。但无法找到错误。 我知道查看别人的代码有点痛苦,但我真的很感激任何帮助。
#include<stdio.h>
#include<string.h>
#include<math.h>
#define PRIME_COUNT 2000
int main()
{
long unsigned int number;
long sieveArray[PRIME_COUNT],primes[PRIME_COUNT],prime_count=0;
int i=2,j,test_cases;
long phi, tempNumber;
memset(sieveArray,0,PRIME_COUNT*sizeof(long));
while(1)
{
if(i>PRIME_COUNT)
break;
if(sieveArray[i]==0)
{
primes[prime_count++]=i;
for(j=i;j<PRIME_COUNT;j=j+i)
{
sieveArray[j]=1;
}
}
i++;
}
scanf("%d",&test_cases);
for(i=0;i<test_cases;i++)
{
scanf("%ld",&number);
if(number!=0)
{
phi=number;
tempNumber=number;
for(j=0;primes[j]*primes[j]<=tempNumber;j++)
{
if(tempNumber%primes[j]==0)
{
phi*=(primes[j]-1);
phi/=primes[j];
while(tempNumber%primes[j]==0)
tempNumber=tempNumber/primes[j];
}
}
if(tempNumber!=1)
{
phi*=(tempNumber-1);
phi/=tempNumber;
}
}
else
phi =number;
printf("%ld\n",phi);
}
return 0;
}
答案 0 :(得分:0)
将您的long
更改为long long
,或者更改
phi*=(tempNumber-1);
phi/=tempNumber;
到
phi/=tempNumber;
phi*=(tempNumber-1);
(以及所有其他类似的行)将临时值保存在数据类型的边界内。首先删除,然后才增加。要了解原因,请考虑number
是否位于最高限额以下的素数时的情况。
顺便提一下,当您if(sieveArray[i]==0)
时,sieveArray[PRIME_COUNT]
会尝试访问i==PRIME_COUNT
数组的一个结尾元素。