思路:对于
,枚举每个数的倍数,然后选出两个最小的数,更新答案,复杂度O(
)
#include<cstdio> const int N=1e7+50; typedef long long LL; int n,x,vis[N],t1,t2,s1,s2; LL ans; int main(){ scanf("%d",&n);ans=1e14; for(int i=1;i<=n;i++){ scanf("%d",&x); if(vis[x])if(ans>x)ans=x,t1=vis[x],t2=i; //相同的数更新下答案 if(!vis[x])vis[x]=i; } for(int i=1;i<N;i++){ if(i>=ans)break;//可能有点用的优化 s1=s2=0;//枚举值 for(int j=i;j<N;j+=i){ if(!vis[j])continue; if(!s1)s1=j,s2=vis[j];//s1为在数组中存在的值 else{ if(ans>1ll*s1*j/i) ans=1ll*s1*j/i,t1=s2,t2=vis[j];//取出两个最小的更新答案 break;//后面的不可能更新答案 } } } if(t1>t2)swap(t1,t2); printf("%d %d\n",t1,t2); }