1748. The Most Complex Number
Time limit: 1.0 second
Memory limit: 64 MB
Let us define a
complexity of an integer as the number of its divisors. Your task is to find the most complex integer in range from 1 to
n. If there are many such integers, you should find the minimal one.
Input
The first line contains the number of testcases
t (1 ≤
t ≤ 100). The
i-th of the following
t lines contains one integer
ni
(1 ≤
ni ≤ 10
18)
.
Output
For each testcase output the answer on a separate line. The
i-th line should contain the most complex integer in range from 1 to
ni and its complexity, separated with space.
Sample
|
题意:给出N,求【1,N】内最大的反素数,如果有多个,输出最小的;
思路:根据15个质数和1构造一棵树,每一层代表一个质数(0,60]的组合,60是根据1e18得出的,然后就递归遍历整棵树就好了,要注义剪枝(如果超出区间就不用往下,右搜了,向右向下剪枝);
失误:好长时间才理解,自己写的一直不过,最后发现竟然是溢出,以后不要轻易乘,能用除法判断别用乘法;
打表的方法就是这道题(如果能打出1e18内的反素数表多方便呀);
AC代码:
#include<cstdio>
typedef unsigned long long LL;
LL p[15]={2,3,5,7,11,13,17,19,23,29,31,37,39,41,43,47};
LL bnum,mcnt,N;
void Tp(LL num,LL cnt,LL limit,LL pos)
{
if(pos>14) return ;//控制深度 防止越界
if(cnt>mcnt||(cnt==mcnt&&num<bnum))//更新结果
{
mcnt=cnt;
bnum=num;
}
LL tem=num,i=0;
for(i=1;i<=limit;++i)//遍历子节点
{
if(tem>N/p[pos]) break;//判断条件换成除法防止溢出 向右剪枝
tem*=p[pos];//子节点所代表的值
Tp(tem,cnt*(i+1),i,pos+1);//递归搜索
}
}
int main()
{
LL T;
scanf("%llu",&T);
while(T--)
{
scanf("%llu",&N);
bnum=mcnt=1;//初始化
Tp(1,1,60,0);
printf("%llu %llu\n",bnum,mcnt);
}
return 0;
}