洛谷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 }
AC代码

 

posted @ 2018-08-29 16:22  garage  阅读(83)  评论(0编辑  收藏  举报