首页 > 代码库 > HDU 4937 Lucky Number (数学,进制转换)

HDU 4937 Lucky Number (数学,进制转换)

题目

 

参考自博客:http://blog.csdn.net/a601025382s/article/details/38517783

 

 

//string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串/*题意:我们将3,4,5,6认为是幸运数字。给定一个十进制数n。现在可以讲起任意转换成其他进制,但转换后的数必须是由3,4,5,6构成的,而这个进制称为幸运进制。问有多少个幸运进制。若有无数个,则输出-1。例如19在5进制下是34,所以5是幸运进制。题解:先考虑特殊情况,所情况下会有无穷个?只有n=3,4,5,6的时候,因为这几个数在大于n的进制下都是他本身。。注意特殊情况不包括33,343这些。因为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<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>using namespace std;#define ll __int64int main(){    int t;    scanf("%d",&t);    for(int id=1;id<=t;id++)    {        int vis[10010];//后期枚举进制除重用的        memset(vis,0,sizeof(vis));        ll n; //注意输入要64位啊~~~        scanf("%I64d",&n);        int ans=0;        if(n>=3&&n<=6)ans=-1;        else         {            for(ll a0=3;a0<7;a0++)            {                for(ll a1=3;a1<7;a1++)                {                    ll x=(n-a0)/a1;                    if((n-a0)%a1==0&&x>max(a0,a1))                    {                            ans++;                        if(x<10010)                            vis[(int)x]=1;                    }                }            }            for(ll a0=3;a0<7;a0++)            {                for(ll a1=3;a1<7;a1++)                {                    for(ll a2=3;a2<7;a2++)                    {                        ll de=a1*a1-4*a0*a2>0;                        if(de>0)                        {                            ll sq=(ll)sqrt((double)de);                            if(sq*sq==de)                            {                                if((sq-a1)%(2*a0)==0)                                {                                    ll x=(sq-a1)/(2*a0);                                    if(x>a0&&x>a1&&x>a2)                                    {                                        ans++;                                        if(x<10010)                                            vis[(int)x]=1;                                    }                                }                            }                        }                    }                }            }            for(int jin=4;jin<=10000;jin++)            {                if(vis[jin]==0)                {                    ll nn=n;                    int flag=1;                    while(nn)                    {                        if(nn%jin>=3&&nn%jin<=6)                        {                            nn=nn/jin;                        }                        else                         {                            flag=0;                            break;                        }                    }                    if(flag)ans++;                }            }        }        printf("Case #%d: %d\n",id,ans);    }    return 0;}
View Code