给你n个数,找到两两lcm的最小值。
果然脑子题还是做不来。。。
枚举gcd,找到最小的两个能被这个gcd整除的数,就是这个gcd对应的答案(如果换成其他数字答案一定更大)
对于所有的gcd找到一个最小值就好了
时间复杂度
O
(
∑
i
=
1
n
n
i
)
=
π
n
O(\sum _{ i=1 }^{ n }{ \frac { n }{ i } } )=\pi n
O(∑i=1nin)=πn
4秒还是有点点紧的
#include<iostream>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
long long n,i,gcd,mx,num,t,lcm,res,resp,resq,p,q;
long long a[2000000],f[10000005][3];
int main()
{
cin>>n;
fo(i,1,n)
{
cin>>a[i]; if (a[i] > mx) mx = a[i];
if (f[a[i]][1] == 0) f[a[i]][1] = i;//大于两次重复的数字舍去
else if (f[a[i]][2] == 0) f[a[i]][2] = i;
}
res = 1e18;
fo(gcd,1,mx)
{
num = 0; t = gcd;
while (t <= mx)
{
if (f[t][1])
{
if (num == 1) {num = 2; q = f[t][1]; break;}
num = 1; p = f[t][1];
}
if (f[t][2])
{
if (num == 1) {num = 2; q = f[t][2]; break;}
num = 1; p = f[t][2];
}
t += gcd;
}
if (num != 2) continue;
lcm = a[p] * a[q] / gcd;
if (lcm < res) {res = lcm; resp = p; resq = q;}
}
if (resp > resq) swap(resp,resq);
cout<<resp<<" "<<resq<<endl;
return 0;
}