题目链接:
http://hihocoder.com/problemset/problem/1165
题意:
从n个中选出两个数来使他们乘积的因子的个数最多。
分析:
对于一个数我们将其进行素因子分解
x= (p1^a1)*(p2^a2)*....*(pn^an);
那么x的因子数为(a1+1)*(a2+1)*...*(an+1);
然后我们可以预处理1到100000的因子的个数,然后
对输入的数据按照因子的个数排下序,然后枚举前200
个数的组合,求一下最大值就好了。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e5+10; int prime[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, }; int a[maxn][66],num[maxn]; void init(){ for(int i=1;i<maxn-8;i++){ int tmp = i; memset(a[i],0,sizeof(a[i])); for(int j=0;j<66&&prime[j]<=tmp;j++){ if(tmp%prime[j]==0){ while(tmp%prime[j]==0){ a[i][j]++; tmp/=prime[j]; } } } } for(int i=1;i<maxn-8;i++){ num[i]=1; for(int j=0;j<66;j++){ num[i]*=(a[i][j]+1); } } } struct ans{ int a,b; bool operator <(const struct ans &tmp)const{ return b>tmp.b; } }p[maxn]; int main() { init(); int n; while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ scanf("%d",&p[i].a); p[i].b=num[p[i].a]; } sort(p,p+n); int rea = 0; if(n>200){ for(int i=0;i<200;i++){ for(int j=i;j<200;j++){ int tmp = 1; for(int t=0;t<66;t++){ tmp*=(a[p[i].a][t]+a[p[j].a][t]+1); } rea=max(rea,tmp); } } } else{ for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ int tmp = 1; for(int t=0;t<66;t++){ tmp*=(a[p[i].a][t]+a[p[j].a][t]+1); } rea=max(rea,tmp); } } } printf("%d\n",rea); } return 0; }