题目链接 http://lightoj.com/volume_showproblem.php?problem=1028
题意:给你一个十进制的数N,把它转化成一个任意进制的数M,并且M的最后一位为0(M为[2,inf)的任意进制),问存在多少种这样的进制。
思路:如果N 转化成x进制符合题目给出的条件,则N=an*x^n+an-1*x^n-1+...+a1*x^n=x*(an*x^n-1+an-1*x^n-2+...a1),a0=0.
问题转化为求N的约数个数。
代码最后给出了一组测试数据,注意N=1的情况。
#include <stdio.h>
const int NUM=1000004;
int prime[80000];
int Num_Prime=0;
bool visit[NUM];
__int64 n;
void Prime () //素数打表prime数组从1开始,范围内最大1000003
{
for (int i=2;i<NUM;i++) if (visit[i] == false)
{
prime[++Num_Prime]=i;
for (int j=i+i;j<NUM;j+=i)
visit[j]=true;
}
}
void Deal ()
{
__int64 ans=1;
int t,id=0;
for (int i=1;i<=Num_Prime && prime[i]*prime[i] <= n;i++)
if(n%prime[i] == 0)
{
t=0;
while (n%prime[i] == 0)
{
t++;
n/=prime[i];
}
ans*=(1+t);
}
if (n>1) //说明n在被处理后留下了大于1000003的素数
ans*=2;
if (ans!=1) //如果n为合数
printf("%lld\n",ans-1);
else //如果n为素数
printf("1\n");
}
int main ()
{
int T;
scanf("%d",&T);
Prime ();
for (int cas=1;cas<=T;cas++)
{
scanf ("%lld",&n); //vc6.0编译需改为I64d
printf("Case %d: ",cas);
if (n == 1)
printf("0\n");
else
Deal ();
}
return 0;
}
/*
3
2592
932832498273
1
Out:
Case 1: 29
Case 2: 31
Case 3: 0
932832498273=3*13*41*317*1840331
*/
2013/4/20 补充:把求约数个数的函数写成了一个类,详见代码
#include <cstdio>
#include <algorithm>
using namespace std;
class Num_divisors
{
private:
bool visit[1000004];
int NUM;
__int64 Deal (__int64 n)
{
__int64 ans=1;
int t,id=0;
for (int i=1;i<=Num_Prime && prime[i]*prime[i] <= n;i++)
if(n%prime[i] == 0)
{
t=0;
while (n%prime[i] == 0)
{
t++;
n/=prime[i];
}
ans*=(1+t);
}
if (n>1) //说明n在被处理后留下了大于1000003的素数
ans*=2;
if (ans!=1) //如果n为合数
return ans-1;
else //如果n为素数
return 1;
}
public:
int prime[80000];
int Num_Prime;
Num_divisors ()
{
Num_Prime=0;
NUM=1000004;
Prime ();
}
void Prime () //素数打表prime数组从1开始,范围内最大1000003
{
for (int i=2;i<NUM;i++) if (visit[i] == false)
{
prime[++Num_Prime]=i;
for (int j=i+i;j<NUM;j+=i)
visit[j]=true;
}
}
__int64 Cal_true (__int64 n) //1-10^12内任意一个数约数的个数,不包括自己
{
if (n==1)
return 1;
return Deal (n);
}
__int64 Cal (__int64 n) //1-10^12内任意一个数约数的个数,包括自己
{
if (n==1)
return 1;
return Deal (n)+1;
}
}ob;
int main ()
{
int T;
__int64 n;
scanf("%d",&T);
for (int cas=1;cas<=T;cas++)
{
scanf ("%lld",&n);
printf("Case %d: ",cas);
if (n == 1)
printf("0\n");
else
printf("%lld\n",ob.Cal_true(n));
}
return 0;
}