参考自博客: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 __int64 int 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; }
HDU 4937 Lucky Number (数学,进制转换),布布扣,bubuko.com
HDU 4937 Lucky Number (数学,进制转换)
原文:http://www.cnblogs.com/laiba2004/p/3908403.html