HDU 4937 Lucky Number 【搜索】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4937

题目大意:给你T组数据,每组数据输入一个小于=1e12的数num,如果这个数的n进制下都是由3,4,5,6这四个数字组成的,则说明这个n进制是num的幸运进制,现在求一个num有几个幸运进制,如果有无限多个幸运进制则输出-1.

题解:

如果输入的num转化后是一位数,显然可以得到3,4,5,6这四个数字应该输出-1。

           如果输入的num转化后是二位数,以base作为进制的话,转换问base进制就是num=a*base+b。就是解这个二元一次方程(num已知;枚举a和b,算得base>max(a,b)即可)

           如果输入的num转化后是三位数,以base作为进制的话,转换为base进制就是num=a*base*base+b*base+c,就是枚举a,b,c算得base>max(a,b,c)即可。

   如果输入的num转化后是四位数及以上,那么其base进制可以枚举的范围是:base>min(3,4,5,6),即base最小是4。而对于其他的情况,我们只用取一个适合的大小的上界,x1+x2*base+x3*base^2+x4*base^3+...>base+x1*base+x2*base^2+x3*base^3,其上界可以取num^(1/3)即可。

   这样省了很多时间。

   

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long

LL getmax(LL a,LL b)
{
    if(a>b) return a;
    else return b;
}

int main ()
{

    LL T,Tt;
    scanf("%d",&T);
    for(LL Tt=1;Tt<=T;Tt++)
    {
        LL num,x1,x2,x3,ans=0;
        scanf("%I64d",&num);

        //如果是3,4,5,6直接输出-1
        if(num>=3 && num<=6) {printf("Case #%I64d: -1\n",Tt);continue;}

        //转化为base进制后是二位 x1*base + x2 = num
        for(x1=3;x1<=6;x1++)
         for(x2=3;x2<=6;x2++)
         {
             if( (num-x2)%x1==0 && (num-x2)/x1>getmax(x1,x2) )  ans++;
         }

        //转换为base进制后是三位
        // x1*base^2 + x2*base + x3 = num
        for(x1=3;x1<=6;x1++)
         for(x2=3;x2<=6;x2++)
          for(x3=3;x3<=6;x3++)
          {
              LL a=x1,b=x2,c=x3-num;
              LL derta=(LL)sqrt(b*b-4*a*c+0.5);
              if(derta*derta!=b*b-4*a*c) continue;
              if( (derta-b)%(2*a)) continue;
              if( (derta-b)/(2*a)>getmax(x1,getmax(x2,x3))) ans++;
          }

        //其他
        for(LL i=4;i*i*i<=num;i++)  //之前把i定义成了int类型,TLE了,是int转LL的时候花了很多时间
        {
            LL t=num;
            while(t)
            {
                if(t%i<3||t%i>6) break;
                t=t/i;
            }
            if(!t) ans++;
        }

        printf("Case #%I64d: %I64d\n",Tt,ans);
    }
}

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值