http://www.spoj.com/problems/NDIV/
这是问题陈述。由于我是编程的新手,这个特殊的问题让我失望,我在互联网上找到了这个特殊的代码,当我尝试提交AC时。我想知道这段代码是如何工作的,因为我已经从在线资源中提交了这个代码,这本身对初学者来说是个坏主意。
#include <bits/stdc++.h>
using namespace std;
int check[32000];
int prime[10000];
void shieve()
{
for(int i=3;i<=180;i+=2)
{
if(!check[i])
{
for(int j=i*i;j<=32000;j+=i)
check[j]=1;
}
}
prime[0] = 2;
int j=1;
for(int i=3;i<=32000;i+=2)
{
if(!check[i]){
prime[j++]=i;
}
}
}
int main()
{
shieve();
int a,b,n,temp,total=1,res=0;
scanf("%d%d%d",&a,&b,&n);
int count=0,i,j,k;
for(i=a;i<=b;i++)
{
temp=i;
total=1;
k=0;
for(j=prime[k];j*j<=temp;j=prime[++k])
{
count=0;
while(temp%j==0)
{
count++;
temp/=j;
}
total *=count+1;
}
if(temp!=1)
total*=2;
if(total==n)
res++;
}
printf("%d\n",res);
return 0;
}
看起来代码在eratosthenes的筛子上起作用,但是有一些我无法理解的东西。
关于这种方法的混淆太多,有人可以解释整个算法它是如何工作的。
答案 0 :(得分:1)
设置数组的硬限制可能是因为问题要求如此?如果不是那么只是坏代码。
在内部循环中,您正在计算分割数字的素数的最大幂。为什么?见第3点。
数字n的因子数可以如下计算:
令n =(p1)^(n1)*(p2)^(n2)...其中p1,p2是素数,n1,n2 ......是它们的指数。那么因子数n =(n1 + 1)*(n2 + 1)......
因此,行total *= count + 1
基本上是total = total * (count + 1)
(其中count
是除以原始数字的素数的最大指数),计算数字的素数因子的数量。
是的,该代码实现了Eratosthenes的筛选,用于在表格中存储素数。
(编辑刚看到问题 - 你需要至少10 ^ 4 boolean
个值来存储素数(你实际上并不需要存储值,只是一个标志指示值是否为素数。。给出的条件为0 <= b - a <= 10^4
,因此从a
开始循环到b
并检查存储在数组中的bool
值知道他们是否是素数。)