BZOJ 1225: [HNOI2001] 求正整数 高精度+搜索+质数

题意:给定n求,有n个因子的最小正整数。

题解:水题,zcr都会,我就不说什么了。

  因数个数球求法应该知道,将m分解质因数,然后发现 a1^p1*a2^p2....an^pn这样一个式子,

  (1+p1)*(1+p2)*...=n,然后用小的质数填坑。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int pri[] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
 5 int n, ans[100005], res[21], tmp[21];
 6 double lg[21], mn=DBL_MAX;
 7 
 8 void input()
 9 {
10     scanf("%d", &n);
11     for(int i=1; i<=16; i++) lg[i] = log(pri[i]);
12 }
13 
14 void dfs(double x, int y, int z){//现在的数是e^x,还剩下y个因子,选到第z个质数
15     if(x >= mn) return;
16     if(y == 1){
17         mn = x;
18         memset(res, 0, sizeof(res));
19         for(int i=1; i<=z-1;i++) res[i]=tmp[i];
20         return;
21     }
22     if(z>16) return;
23     for(int i = 0; (i+1)*(i+1)<=y; i++){
24         if(y%(i+1)==0)
25         {
26             if(i != 0){
27                 tmp[z] = i;
28                 dfs(x+lg[z]*i, y/(i+1), z+1);
29             }
30             if((i+1)*(i+1)!=y){
31                 tmp[z] = y/(i+1)-1;
32                 dfs(x+lg[z]*(y/(i+1)-1), i+1, z+1);
33             }
34         }
35     }
36 }
37 
38 void work()
39 {
40     dfs(0, n, 1);
41 }
42 
43 void output()
44 {
45     ans[0]=ans[1]=1;
46     for(int i=1;i<=16;i++){
47         for(;res[i]>0;res[i]--){
48             for(int j=1;j<=ans[0];j++) ans[j]*=pri[i];
49             for(int j=1;j<=ans[0];j++) ans[j+1]+=ans[j]/10, ans[j]%=10;
50             if(ans[ans[0]+1]!=0) ans[0]++;
51             while(ans[ans[0]]/10!=0){
52                 ans[ans[0]+1] += ans[ans[0]]/10;
53                 ans[ans[0]] %= 10;
54                 ++ans[0];
55             }
56         }
57     }
58     for(int i = ans[0]; i>=1; i--){
59         printf("%d", ans[i]);
60     }
61     printf("\n");
62 }
63 
64 int main()
65 {
66     input();
67     work();
68     output();
69     return 0;
70 }

 

posted @ 2017-11-01 14:30  Kaiser-  阅读(142)  评论(0编辑  收藏  举报