URAL 1748 The Most Complex Number 【区间最大反素数(模板)】

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

input output
5
1
10
100
1000
10000
1 1
6 4
60 12
840 32
7560 64

题意:给出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;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值