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

题意:

我们将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 __int64
const 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;
}


你可能感兴趣的:(hdu 4937 Lucky Number 数学(进制转换))