洛谷P1463 反素数
经典题了,很难想到这TM是搜索......
题意:求[1, n]中约数最多的数中最小的。
解:我们有约数个数定理。
所以考虑通过枚举每个质因数个数来直接计算出约数个数。
然后就可以搜索了。
注意:若p1 < p2 则 a1 >= a2 否则交换a1 a2更优
注意:质数求25以内的即可。因为乘起来已经爆int了。
多说无益,看代码。
1 #include <cstdio> 2 #include <algorithm> 3 typedef long long LL; 4 const int N = 110; 5 6 int p[N], top, lim[N]; 7 bool vis[N]; 8 LL s[N], n; 9 10 inline void getp(int b) { 11 for(int i = 2; i <= b; i++) { 12 if(!vis[i]) { 13 p[++top] = i; 14 } 15 for(int j = 1; j <= top && i * p[j] <= b; j++) { 16 vis[i * p[j]] = 1; 17 if(i % p[j] == 0) { 18 break; 19 } 20 } 21 } 22 for(int i = 1; i <= top; i++) { 23 LL t = p[i]; 24 while(t <= n) { 25 t *= p[i]; 26 lim[i]++; 27 } 28 } 29 return; 30 } 31 32 LL ans = 1, cnt = 1; 33 void DFS(LL now, LL s, int t, int last) { 34 if(now > n) { 35 return; 36 } 37 if(t == top + 1 || last == 0) { 38 if(cnt < s) { 39 cnt = s; 40 ans = now; 41 } 42 else if(cnt == s) { 43 ans = std::min(ans, now); 44 } 45 return; 46 } 47 48 LL tp = now; 49 for(int i = 0; i <= lim[t] && i <= last && tp <= n; i++) { 50 DFS(tp, s * (i + 1), t + 1, i); 51 tp *= p[t]; 52 } 53 return; 54 } 55 56 int main() { 57 scanf("%lld", &n); 58 getp(25); 59 LL t = 1; 60 for(int i = 0; i <= lim[1]; i++) { 61 DFS(t, i + 1, 2, i); 62 t *= 2; 63 } 64 65 printf("%lld", ans); 66 return 0; 67 }