题目连接:http://acm.fzu.edu.cn/problem.php?pid=1607
思路:可以直接利用素数打表,然后分解质因数,计算因数的个数
最后个数-1就是答案,然后再枚举最小的因数就可以了
我的代码:
int prime[500000];
int num=0;
bool flag[1000005];
void init()
{
__int64 i,j;
memset(flag,0,sizeof(flag));
flag[1]=true;
flag[0]=true;
for(i=2;i<1000005;i++)
{
if(!flag[i])
{
prime[num++]=(int)i;
for(j=i*i;j<1000005;j=j+i)
flag[j]=true;
}
}
}
void slove(int n)
{
int i,time,res=1,ans;
int N=n;
bool flag=true;
for(i=0;prime[i]*prime[i]<=n;i++)
{
time=0;
if(n%prime[i]==0)
{
n=n/prime[i];
time++;
while(n%prime[i]==0)
{
n=n/prime[i];
time++;
}
res=res*(time+1);
if(flag)
{
flag=false;
ans=prime[i];
}
}
if(n==1)
break;
}
time=0;
if(n>1)
{
time++;
res=res*(time+1);
if(flag)
{
flag=false;
ans=n;
}
}
printf("%d %d/n",res-1,N/ans);
}
int main()
{
int n;
init();
while(scanf("%d",&n)!=EOF)
{
if(!flag[n])
{
printf("1 1/n");
continue;
}
slove(n);
}
return 0;
}
还有一份代码,居然超时了。。很悲剧
using namespace std;
bool isprime(int n)
{
int i;
for(i=2;i*i<=n;i++)
if(n%i==0)
return false;
return true;
}
int count(int n)
{
int i,m,ans=0;
m=(int)sqrt((double)(n));
for(i=1;i<=m;i++)
ans=ans+n/i;
return (ans<<1)-m*m;
}
int main()
{
int n,ans1,ans2,i;
while(scanf("%d",&n)!=EOF)
{
if(isprime(n))
{
printf("1 1/n");
continue;
}
ans1=count(n)-count(n-1);
for(i=2;i<=n;i++)
if(n%i==0)
{
ans2=n/i;
break;
}
printf("%d %d/n",ans1-1,ans2);
}
return 0;
}