首页 > 代码库 > HDU 4937 Lucky Number 【搜索】
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); } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。