把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100) 第2 - T + 1行:T个数,表示需要计算的n。(1 <= n <= 10^18)
OutPut
共T行,每行2个数用空格分开,第1个数是答案,第2个数是约数的数量。
Input示例
5 1 10 100 1000 10000
Output示例
1 1 6 4 60 12 840 32 7560 64
解题思路:寻找该区间内最大的反素数即为答案。
反素数具有两个性质
(1)反素数为从2开始的连续的素数幂的乘积
(2)假设x=p1^a1*p2^a2*p3^a3....,则肯定满足p1>=p2>=p3
我们可以利用上述两条性质利用dfs+剪枝来搜索。
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <string> #include <vector> #include <deque> #include <queue> #include <stack> #include <map> #include <set> #include <utility> #include <algorithm> #include <functional> using namespace std; /* 反素数的性质: (1) 一个反素数的质因子必然是从2开始连续的质数 (2) p=2^t1*3^t2*5^t3*7^t4...,必然t1>=t2>=t3.... */ typedef unsigned long long ull; const ull inf = 0x3f3f3f3f3f3f3f3fLL; int prime[20] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59 }; ull n; ull ans; ull maxnum; int T; void dfs(int pos, int lim, ull cur, ull num) { if(pos > 15) return ; if(cur > n) return ; if(num > maxnum) { maxnum = num; ans = cur; } if(num == maxnum && cur < ans) { ans = cur; } for(int i = 1; i <= lim; ++i) { if(n / prime[pos] < cur) break; dfs(pos + 1, i, cur * prime[pos], num * (i + 1)); cur *= prime[pos]; } return ; } int main() { cin >> T; while(T--) { cin >> n; maxnum = 0; ans = inf; dfs(0, 60, 1, 1); cout << ans << " " << maxnum << endl; } return 0; }