幽香今天心情不错,正在和花田里的虫子玩一个益智游戏。
这个游戏是这样的,对于一个数组A,幽香从A中选择一个数a,虫子从A中选择一个数b。a和b可以相同。她们的分数是a*b的因子的个数。
幽香和虫子当然想要获得尽可能的高的分数,你能告诉她们应该选择哪两个数吗。
由于幽香是个非常随意的人,数组A中的元素都是她随机选择的。
输入
一行一个数n,表示A中整数的数量。
接下来一行n个数,分别表示a1,a2,...,an,为A中的元素。
n <= 100000, 1 <= ai <= 100000
保证所有的ai都是随机生成的。
输出
一行表示最大的分数。
2 3 4
6http://hihocoder.com/problemset/problem/1165?sid=415097
知识点:一个数的因子数等于它完全分解为质数后,每一项质数个数加一连乘的结果。比如75=3*5*5,那么它的因子数为(1+1)*(2+1)=6。其实这个结论特别好证明,每一个因子数可以取0到它的个数个。比如,每个都取0个,那么结果即为1。如果每个都取,那么结果为那个数本身。
预处理下1-100000的因子数,然后将读进来的数按因子数多少排个序,然后取其前n(当n<100)或者前100个计算,取最大值即可。
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
struct node{
int a,b,c; //a代表质因子的种类数 b代表质因子总的个数
};
node y[100010];
int num[105];
int cmp(node p,node q){
if(p.a!=q.a)
return p.a>q.a;
else
return p.b>q.b;
}
ll cal(ll x){ //很好的求因子个数的模板
memset(num,0,sizeof(num));
int cnt=0;
for(ll i=2;i*i<=x;i++){
if(x%i==0){
cnt++;
while(x%i==0){
num[cnt]++; x/=i;
}
}
}
if(x>1) num[++cnt]++;
ll res=1;
for(int i=1;i<=cnt;i++){
res*=(num[i]+1);
}
return res;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;++i){
cin>>y[i].c;
int p=y[i].c;
y[i].a=0;y[i].b=0;
for(int j=2;j*j<=p;++j){ //求素因子种类和个数的模板
if(p%j==0){
y[i].a++;
while(p%j==0){
y[i].b++;
p/=j;
}
}
}
if(p>1){
y[i].a++;
y[i].b++;
}
}
sort(y,y+n,cmp);
ll max=0;
for(int i=0;i<min(n,100);++i){
for(int j=i;j<min(n,100);++j){
ll w=cal((ll)y[i].c*y[j].c); //特别要注意这里的(ll)
if(w>max)
max=w;
}
}
cout<<max<<endl;
}
return 0;
}