CF 1154G Minimum Possible LCM

题目链接

我是题目链接戳我呀>_<

题面

在这里插入图片描述

题目大意

给出长度为n的数组,求其中最小公倍数最小的一对数的数组下标。

题目分析

n的范围为 1 ≤ n ≤ 106 ,二重循环遍历数组一定会超时。ai的范围为 1 ≤ n ≤ 107 ,因此可以遍历因子,寻找在数组中出现并为该因子的倍数的最小的两个数,求其最大公倍数。公倍数最小的两个数的对应下标即为答案。出现次数超过两次,其本身可算为最小公倍数,与答案比较。注意中间计算会爆int。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7;
int vis[10000010],num[1000010];
int main()
{
    //clock_t start=clock();
    int n,ans1=0,ans2=0;
    ll ans=(ll)maxn*(ll)maxn;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&num[i]);
        if(vis[num[i]]&&ans>num[i]){
            ans=min(ans,(ll)num[i]);
            ans1=vis[num[i]];ans2=i;
        }
        vis[num[i]]=i;
    }
    for(int i=1;i<=maxn;i++){
        int sum=0,bigger=0;
        for(int j=i;j<=maxn;j+=i){
            if(!vis[j]) continue;
            sum++;
            if(!bigger){
                bigger=j;
            }
            if(sum==2){
                ll another=(ll)bigger*(ll)j/(ll)i;
                //cout<<ans<<" "<<another<<endl;
                if(another<ans){
                    ans=another;
                    ans1=vis[j];
                    ans2=vis[bigger];
                }
                //cout<<bigger<<" "<<j<<endl;
                break;
            }
        }
    }
    printf("%d %d\n",min(ans1,ans2),max(ans1,ans2));
    //cout<<clock()-start<<endl;
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值