hdu 4937 Lucky Number 进制转换-枚举/数学

题意:我们将3,4,5,6认为是幸运数字。给定一个十进制数n。现在可以讲起任意转换成其他进制,但转换后的数必须是由3,4,5,6构成的,而这个进制称为幸运进制。问有多少个幸运进制。若有无数个,则输出-1。例如19在5进制下是34,所以5是幸运进制。



//我们将n这个数在x进制下的表示记为:n=a0+a1*x+a2*x^2+a3*x^3+..... 

我们发现当n表示为x进制下的四位数时,就有  a3*x^3+.....而n最大只有1e12,因此x最大就只需要取到 10000 即可表示所有1e12内的数,


首先如果n表示为X进制,  当n是一位数时,显然只有 n= 3 4 5 6符合要求,当然此后所有进制下,n都合法,因此答案-1。

当n表示为2位数, //case1 n=a0+a1*x;,我们只需要枚举a0,a1就可以得到x的个数

当n表示为三位数 //case2 n=a0+a1*x+a2*x^2,我们需要解这个一元二次方程,判断解x是否为正整数,


当n表示为4位数以及以上时     显然X进制小最小的四位数也是 x^3啦,因此 只要n>=x^3,我们就可以确保 n至少会被表示为大于等于四位数。

因此只要枚举符合x^3<=n的所有x即可,显然x不超过1w个  因此复杂度没问题



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

__int64 max(__int64 a,__int64  b)
{return a>b?a:b;}
const double pi=acos(-1.0);
double eps=0.00000001; 
int main()
{
	
	
	int t;cin>>t;
	int cnt=1;
	while(t--)
	{
		__int64 n;
		scanf("%I64d",&n);
		//case0		
		if (n==3||n==4||n==5||n==6)
		{
			printf("Case #%d: -1\n",cnt++); continue;
		} 
		__int64 i,j,k;
		__int64 ans=0;
		//我们将n这个数在x进制下的表示记为:n=a0+a1*x+a2*x^2+a3*x^3+.....
		
		//case1 n=a0+a1*x;
		for (i=3;i<=6;i++) 
			for (j=3;j<=6;j++) 
				if ((n-i)%j==0)
					if ((n-i)/j>max(i,j))ans++;  
					
					//case2 n=a0+a1*x+a2*x^2
					//a2 *  x^2  + a1* x +a0-n=
					//del=sqrt(a1*a1-4*a2*(a0-n))0
					//x1= (-a1+del) /2/a2;
					//x2= (-a1-del)/2/a2;
					
					for (i=3;i<=6;i++)		
					{
						for (j=3;j<=6;j++)
						{
							for (k=3;k<=6;k++)
							{
								if (j*j-4*k*(i-n)<0) continue;
								__int64 del=(__int64)sqrt(j*j-4*i*(k-n)+0.5);
								if (del*del!=j*j-4*i*(k-n))continue;		//判断是否整数
								if ((-j+del)%(2*i))continue;
								__int64 x=(-j+del)/(2*i);	
								if(x>max(max(i,j),k)) ans++;				//进制数必须大于各位数
									if ((-j-del)%(2*i))continue;
								__int64 x2=(-j-del)/(2*i); 
								if (x==x2) continue;
								if(x2>max(max(i,j),k)) ans++; 
							} 
						}
					}
					
					for(i=1;i*i*i<=n;i++)//i进制下最小的四位数是 i^3,如果n>=i^3,则n一定是会被表示为i进制下的至少四位数的数,由于n_max=1e12,因此i最多枚举到1w就OK
					{
						__int64 tmp=n; 
						int fail=0;
						while(tmp)
						{
							__int64 test=tmp%i;
							tmp/=i;
							if (test>=3&&test<=6)
								continue;
							else
							{fail=1;break;}
						}
						if (!fail) 
							ans++; 
					}
					printf("Case #%d: %I64d\n",cnt++,ans);
	} 
	return 0;
	
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值