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

时间:2021-09-08 09:58:51

题目

参考自博客: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=;id<=t;id++)
{
int vis[];//后期枚举进制除重用的
memset(vis,,sizeof(vis));
ll n; //注意输入要64位啊~~~
scanf("%I64d",&n);
int ans=;
if(n>=&&n<=)ans=-;
else
{
for(ll a0=;a0<;a0++)
{
for(ll a1=;a1<;a1++)
{
ll x=(n-a0)/a1;
if((n-a0)%a1==&&x>max(a0,a1))
{
ans++;
if(x<)
vis[(int)x]=;
}
}
} for(ll a0=;a0<;a0++)
{
for(ll a1=;a1<;a1++)
{
for(ll a2=;a2<;a2++)
{
ll de=a1*a1-*a0*a2>;
if(de>)
{
ll sq=(ll)sqrt((double)de);
if(sq*sq==de)
{
if((sq-a1)%(*a0)==)
{
ll x=(sq-a1)/(*a0);
if(x>a0&&x>a1&&x>a2)
{
ans++;
if(x<)
vis[(int)x]=;
}
}
}
}
}
}
} for(int jin=;jin<=;jin++)
{
if(vis[jin]==)
{
ll nn=n;
int flag=;
while(nn)
{
if(nn%jin>=&&nn%jin<=)
{
nn=nn/jin;
}
else
{
flag=;
break;
}
}
if(flag)ans++;
}
} }
printf("Case #%d: %d\n",id,ans);
}
return ;
}