51nod1060 最复杂的数
题意:输入一个数n(n<1e18),找到一个数x,使得x<n,且x的约数最多
题解:满足题目条件的是反素数,网上反素数的介绍:
反素数的定义:对于任何正整数n,其约数个数记为f(n),例如f(6)=4,如果某个正整数n满足:对任意的正整数(0<i<n),都有f(i)<f(n),那么称n为反素数。
从反素数的定义中可以看出两个性质:
(1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小
(2)同样的道理,如果n=2^t1*3^t2*...,那么必有t1>=t2>=t3...
所以这里可以直接dfs+剪枝
#include <bits/stdc++.h> #define maxn 100010 #define INF 0x3f3f3f3f typedef long long ll; using namespace std; ll prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41, 43, 47, 53, 57}; ll n, ans, ma, num; void dfs(ll x,ll deep,ll v){ if(x > n/prime[deep]){ if(v > ma) ma = v, ans = x; else if(v == ma) ans = min(ans, x); return ; } ll t = prime[deep], temp = num; for(ll i=1;i<=temp;i++){ if(x <= n/t){ num = i; dfs(x*t, deep+1, v*(i+1)); t *= prime[deep]; num = temp; } else break; } } int main(){ ll T; scanf("%lld", &T); while(T--){ ma = 0, num = 61, ans = INF; scanf("%lld", &n); dfs(1, 0, 1); printf("%lld %lld\n", ans, ma); } return 0; }
posted on 2018-03-20 21:43 2855669158 阅读(144) 评论(0) 编辑 收藏 举报