标签:style blog http color os io for ar
题意:
有一个数n,问有多少个进制x(基数)使得n转换为x进制后的数字中只有3、4、5、6四个数。
算法:
以上来自于http://blog.csdn.net/lyhvoyage/article/details/38532471
其实大多数是官方题解上的,多了最后那个为什么只要枚举到7000就可以了。。因为x^3以内的已经足以表示n的最大值了。
P.S
菜鸟的神思维记录开始---->
比赛的时候是想到了 进制转换就是把 n表示成 a0 + a1*x+a2*(x^2) + a3*(x^3)+....的形式。
但是碍于时限是1s而且n的范围有1e^12,心想O(n)的复杂度都过不了啊。。。而且也想不通难道还有O(logn)的算法?
这种情况下一般是找规律神马的吧。。。不是有循环节就是有什么特殊的规律吧。。。暴力打表看看吧。。。。
于是在偏离比较正确的思路的道路上越走越远!
其实3-6的循环即使是3个for也完全没什么复杂度啊- -也就4^3而已。。。
为什么算法一定要和n有关呢。。。真是死脑筋。。。。笨得要死啊。。。。
最近好几次都是因为估算复杂度有误导致不敢想和写啊。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
ll max(ll x,ll y)
{
return x>y?x:y;
}
int main()
{
int T,cas=1;
ll n,ans;
scanf("%d",&T);
while(T--)
{
scanf("%I64d",&n);
printf("Case #%d: ",cas++);
ans = 0;
if(n>=3 && n<=6)
{
printf("-1\n");
continue;
}
for(ll i=3;i<=6;i++)
{
for(ll j=3;j<=6;j++)
{
if((n-i)%j==0 && (n-i)/j>max(i,j)) //进制数必须要大于转化后每一位出现的数
ans++;
}
}
for(ll i=3;i<=6;i++)
{
for(ll j=3;j<=6;j++)
{
for(ll k=3;k<=6;k++)
{
ll a=i,b=j,c=k-n,delta;
delta = (ll)sqrt(b*b-4*a*c+0.5);
if(delta*delta!=(b*b-4*a*c)) continue; //如果b*b-4*a*c不是完全平方数
if((delta-b)%(2*a)) continue; //如果解不是整数
ll tmp = (delta-b)/(2*a);
if(tmp>max(i,max(j,k)))
ans++;
}
}
}
for(ll i=4;i*i*i<n;i++)
{
ll tmp = n;
while(tmp)
{
ll x = tmp%i;
if(x<3 || x>6) break;
tmp/=i;
}
if(!tmp) ans++;
}
printf("%I64d\n",ans);
}
return 0;
}
hdu 4937 Lucky Number ( 进制转换+枚举 ),布布扣,bubuko.com
hdu 4937 Lucky Number ( 进制转换+枚举 )
标签:style blog http color os io for ar
原文地址:http://blog.csdn.net/u012841845/article/details/38541775