题意:
用任意进制base去表示十进制数n,若base进制表示的数的每一位都是3,4,5,6中的其中一个数,则该进制base 是幸运base
给你一个n,求base的数目,若base 为无穷,输出-1
其中1<= n <= 1e12
方法:
若n用base进制表示: 若base进制只有一位, 明显可以得出n= 3 || n= 4 || n==5|| n==6 ,且该情况下 ans为无穷,因为当base>= 7都是符合条件的
若base进制下有两位, 可以得出 a*base+ b= n , a,b= 3,4,5,6
同理: 当base进制下为3位时,a*base*base + b*base +c= n,a,b,c= 3,4,5,6
当base进制大于3位时, 因为n最大为1e12, 所以base最大为10000,最小为4, 暴力枚举即可
自己的问题:
在比赛的时候,我就想到两位数的时候,进制最大可以为n/3, 然后就觉得枚举进制不可行的。。。 然后就一直在想枚举位数。。。 都没想三位数和四位数的进制情况
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define LL __int64
int hash[10005];
int main()
{
int T;
scanf("%d",&T);
for(int C= 1; C<= T; C++)
{
memset(hash, 0, sizeof(hash));
LL n;
scanf("%I64d",&n);
if(n==3 || n== 4 || n== 5 || n==6)
{
printf("Case #%d: -1\n",C);
continue;
}
LL ans= 0;
LL base;
for(int a= 3; a<= 6; a++)
for(int b= 3; b<= 6; b++)
{
LL m= n- b;
if(m%a== 0)
{
base= m/ a;
if(base> a && base > b)
{
ans++;
if(base<= 10000)
hash[base]++;
}
}
}
for(int a= 3; a<= 6; a++)
for(int b= 3; b<= 6; b++)
for(int d= 3; d<= 6; d++)
{
LL c= d- n;
LL xx= b*b- 4*a*c;
if(xx< 0)
continue;
double x1= (-b + sqrt(1.0*xx))/(2*a);
LL x2= x1;
LL x3= x2+1;
if(a*x2*x2+ b*x2+ c== 0 && x2> a && x2> b && x2> d)
{
if(x2<= 10000)
hash[x2]++;
ans++;
}
if(a*x3*x3+ b*x3+ c== 0 && x3> a && x3> b && x3> d)
{
if(x3<= 10000)
hash[x3]++;
ans++;
}
}
for(int base= 4; base<= 10000; base++)
{
LL m= n;
int flag= 1;
while(m)
{
LL num= m%base;
if(num!= 3 && num!=4 && num!= 5 && num!= 6)
{
flag= 0;
break;
}
m/= base;
}
if(flag&& !hash[base])
if(flag)
{
ans++;
hash[base]++;
}
}
printf("Case #%d: %I64d\n",C, ans);
}
return 0;
}