hdu 4937 Lucky Number 数学(进制转换)

来源:互联网 发布:淘宝u站怎么进入 编辑:程序博客网 时间:2024/06/05 15:23

题意:

我们将3,4,5,6认为是幸运数字。给定一个十进制数n。现在可以讲起任意转换成其他进制,但转换后的数必须是由3,4,5,6构成的,而这个进制称为幸运进制。问有多少个幸运进制。若有无数个,则输出-1。例如19在5进制下是34,所以5是幸运进制。

题解:

先考虑特殊情况,所情况下会有无穷个?只有n=3,4,5,6的时候,因为这几个数在大于n的进制下都是他本身。。注意特殊情况不包括33,343这些(我一开始就死在这里了,wa了三次)。因为33在34进制下就不是33了(类似于10在16进制下就是A了)。

我们知道n=a0+a1*x+a2*x^2+...,其中x为进制。由于n达到1e12,所以我们分情况讨论。

1)a0形式,我们已经在特殊情况中指出,只有无穷个的时候才会符合条件

2)a0+a1*x形式,枚举a0,a1,我们判断(n-a0)是否能被a1整除,以及x是否大于max(a0,a1)即可。

3)a0+a1*x+a2*x^2,我们枚举a0,a1,a2,那么就相当于解一元二次方程。判断是否有整数解,是否整数解x>max(a0,a1,a2)即可。

4)不在上述三种形式内的,那么进制x最大也不会x^3>n,不然就会变成上述三种的形式。我们就可以枚举进制然后判断是否为幸运进制了。由于x^3<=n,所以复杂度只有1e4。



#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <vector>#include <map>#include <iostream>#include <algorithm>using namespace std;#define LL __int64const int maxn=1e5+10;int main(){    //freopen("D:\\in.txt","r",stdin);    int T;    scanf("%d",&T);    int tt=0;    while(T--)    {        LL n,t,ans=0;        LL i,j,k;        LL a,b,c,d,x;        scanf("%I64d",&n);        if(n>=3&&n<=6){printf("Case #%d: -1\n",++tt);continue;}        //a1+a2*x,x>max(a1,a2)        for(i=3;i<=6;i++)        {            for(j=3;j<=6;j++)            {                if((n-i)%j==0&&(n-i)/j>max(i,j))                {                    //printf("   %I64d+%I64d*%I64d\n",i,j,(n-i)/j);                    ans++;                }            }        }        for(i=3;i<=6;i++)        {            for(j=3;j<=6;j++)            {                for(k=3;k<=6;k++)                {                    a=i;b=j;c=k-n;                    d=(LL)sqrt(b*b-a*c*4+0.5);                    if(d*d!=b*b-a*c*4)continue;                    if((d-b)%(a*2))continue;                    x=(d-b)/(a*2);                    if(x>max(max(i,j),k))                    {                        //printf("   %I64d+%I64d*%I64d+%I64d*%I64d^2\n",k,j,x,i,x);                        ans++;                    }                }            }        }        for(i=2;i*i*i<=n;i++)        {            t=n;            while(t)            {                if(t%i<3||t%i>6)break;                t=t/i;            }            if(!t)            {                ans++;            }        }        printf("Case #%d: %I64d\n",++tt,ans);    }    return 0;}


原创粉丝点击